notte-functions-doctor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Notte Functions Doctor

Notte Functions Doctor

A user-triggered repair tool for a broken Notte Function. The user already knows a Function is failing - this skill's job is to find out why, fix it when it is fixable, verify the fix without disturbing the live Function, and promote it only with explicit approval.
The hard part of repair is not editing code - it is diagnosis. A broken scrape usually does not error; it silently returns
[]
or garbage because a selector or endpoint moved. This skill leans on the Function's health contract (stamped by notte-functions-build) and its last good run to know what "correct" looks like, then works backward from the failure.
Relationship to notte-functions-build. Doctor reuses that skill's two engines - exploration (find the new stable path) and self-test (verify against the contract) - pointed at an existing Function instead of a blank one. It also builds on the base notte-browser skill. Load those for the full command reference.
一款由用户触发的、用于修复损坏的Notte Function的工具。用户已知某个Function出现故障——本技能的任务是找出故障原因,在可修复时进行修复,在不影响在线Function的前提下验证修复效果,且仅在获得明确批准后推广修复。
修复的难点不在于编辑代码,而在于诊断。损坏的爬虫通常不会报错;它会静默返回
[]
或无效数据,因为选择器或端点已变动。本技能依托Function的健康契约(由notte-functions-build生成)及其上一次成功运行记录,明确“正确”的结果是什么,然后从故障反向排查。
与notte-functions-build的关系。Doctor技能复用了该技能的两大引擎——探查(找到新的稳定路径)和自测试(根据契约验证)——但针对的是已存在的Function而非空白Function。它还基于基础的notte-browser技能构建。加载这些技能可查看完整命令参考。

What this skill can and cannot fix

本技能可修复与不可修复的故障

Be honest about the boundary. Not every failure is a code fix, and flailing on an unfixable one wastes runs and can make things worse.
Failure classDoctor's action
Selector / endpoint drift (runs OK, returns empty/wrong shape)Fix - re-explore, patch, verify, promote
Hard exception in
run()
Fix - re-explore the failing step, patch
Expired credentials / auth wallDiagnose and report - the user must refresh the vault/persona; not a code fix
Anti-bot block / captchaDiagnose and advise - suggest
--proxy
/ a trusted profile; captcha solving is already on. Do not blindly retry
Site genuinely gone or restructuredReport - confirm the new target/intent with the user before rebuilding
For the non-code-fixable classes, stop after diagnosis and tell the user the root cause and remedy. Do not edit code hoping it helps.
请明确边界。并非所有故障都能通过代码修复,在不可修复的故障上盲目尝试会浪费运行资源,甚至可能使情况恶化。
故障类别Doctor技能的操作
选择器/端点漂移(运行正常,但返回空值/错误格式)修复——重新探查、补丁修复、验证、推广
run()
方法中出现严重异常
修复——重新探查故障步骤、补丁修复
凭证过期/权限墙诊断并报告——用户必须刷新密钥/身份信息;这不属于代码修复范畴
反机器人拦截/验证码诊断并建议——建议使用
--proxy
/可信配置文件;验证码解决功能已启用。请勿盲目重试
网站确实已下线或重构报告——在重新构建前与用户确认新的目标/需求
对于非代码可修复的类别,诊断完成后停止操作,告知用户根本原因和解决办法。不要试图通过编辑代码解决此类问题。

The pipeline

修复流程

Phase 0  Setup            ensure the notte CLI is authenticated
Phase 1  Identify         locate the broken Function from the user's reference
Phase 2  Recover          recover the contract: response model + last good run    (what "correct" is)
Phase 3  Diagnose         read the failed run; classify the failure
Phase 4  Re-explore       drive the live site; find the new stable path           (drift/exception only)
Phase 5  Verify           patch; verify on an isolated copy against the contract
Phase 6  Promote          show diff + root cause; update the live Function        [GATE]

Phase 0  准备工作            确保notte CLI已完成身份验证
Phase 1  定位故障Function    根据用户提供的信息找到损坏的Function
Phase 2  恢复契约            恢复契约:响应模型 + 上一次成功运行记录    (明确“正确”的标准)
Phase 3  诊断故障            读取失败运行记录;对故障进行分类
Phase 4  重新探查            访问当前在线网站;找到新的稳定路径           (仅针对漂移/异常故障)
Phase 5  验证修复            补丁修复;在隔离副本上根据契约验证修复效果
Phase 6  推广修复            展示差异 + 根本原因;更新在线Function        [确认环节]

Phase 0 - Setup

Phase 0 - 准备工作

bash
notte auth status
If auth is missing, follow the notte-browser auth handling.

bash
notte auth status
如果未完成身份验证,请遵循notte-browser身份验证处理流程。

Phase 1 - Identify the broken Function

Phase 1 - 定位故障Function

Locate the Function from whatever the user gave (an id, a name, "my Indeed function").
If they gave an ID, go straight to
notte functions show --function-id "{function_id}"
. If they gave a name, you have to search - and
functions list
is paginated, so a single call is not a search:
  • it defaults to 10 items per page,
  • the API caps
    --page-size
    at 100,
  • the CLI prints a bare JSON array and drops the
    has_next
    field, so the only way to know you have reached the end is a page shorter than the page size.
Page until a short page comes back. Never conclude a Function is missing from one request:
bash
undefined
根据用户提供的信息(ID、名称、“我的Indeed函数”等)找到对应的Function。
如果用户提供了ID,直接执行
notte functions show --function-id "{function_id}"
。如果用户提供的是名称,你需要进行搜索——
functions list
是分页的,因此单次调用不算完整搜索:
  • 默认每页显示10条数据,
  • API限制
    --page-size
    最大为100
  • CLI会输出一个纯JSON数组,且不返回
    has_next
    字段,因此判断是否到达末尾的唯一方法是返回的页面数据量小于页面大小。
持续分页直到返回的页面数据量不足。切勿仅凭一次请求就判定Function不存在:
bash
undefined

Print every Function, one JSON object per line. Pass --include-deleted to

打印所有Function,每行一个JSON对象。添加--include-deleted参数可包含已删除的Function。

include deleted ones.

all_functions() { local page=1 batch while :; do batch=$(notte functions list --page "$page" --page-size 100 "$@" -o json) || return 1 jq -e 'length > 0' <<<"$batch" >/dev/null || break jq -c '.[]' <<<"$batch" jq -e 'length == 100' <<<"$batch" >/dev/null || break page=$((page + 1)) done }
all_functions() { local page=1 batch while :; do batch=$(notte functions list --page "$page" --page-size 100 "$@" -o json) || return 1 jq -e 'length > 0' <<<"$batch" >/dev/null || break jq -c '.[]' <<<"$batch" jq -e 'length == 100' <<<"$batch" >/dev/null || break page=$((page + 1)) done }

Search live Functions by name

按名称搜索在线Function

all_functions | jq -r 'select(.name | test("indeed"; "i")) | "(.function_id) (.name)"'
notte functions show --function-id "{function_id}" -o json

**If it still does not turn up, check whether it was deleted rather than broken.** `functions list` hides deleted records by default:

```bash
all_functions --include-deleted | jq -r 'select(.name | test("indeed"; "i")) | "\(.function_id)  \(.name)"'
A deleted Function is not a repair job - report it and ask the user whether to recreate it.
notte functions show --function-id "{function_id}"
returns the Function's metadata plus a download URL for its workflow file (the
url
field) - it does not inline the source. Record the name and description, then download the current source so you can read its contract and diff your fix against it later:
bash
URL=$(notte functions show --function-id "{function_id}" -o json | jq -r '.url')
curl -L "$URL" -o current_function.py
Capture the schedule now if there is one. The CLI can set (
schedule
) and remove (
unschedule
) a cron, but it cannot read one back -
functions show
returns no cron field. If the Function is scheduled, get the exact cron expression from the user (or the Notte console) and record it now, so you can re-apply it verbatim after the repair (Phase 6).

all_functions | jq -r 'select(.name | test("indeed"; "i")) | "(.function_id) (.name)"'
notte functions show --function-id "{function_id}" -o json

**如果仍未找到,请检查它是否已被删除而非损坏。**`functions list`默认隐藏已删除的记录:

```bash
all_functions --include-deleted | jq -r 'select(.name | test("indeed"; "i")) | "\(.function_id)  \(.name)"'
已删除的Function无需修复——告知用户并询问是否需要重新创建。
notte functions show --function-id "{function_id}"
会返回Function的元数据及其工作流文件的下载URL
url
字段)——不会内联源代码。记录Function的名称描述,然后下载当前源代码,以便后续读取契约并对比修复差异:
bash
URL=$(notte functions show --function-id "{function_id}" -o json | jq -r '.url')
curl -L "$URL" -o current_function.py
**如果Function有定时任务,请立即记录定时规则。**CLI可以设置(
schedule
)和移除(
unschedule
) cron表达式,但无法读取——
functions show
不会返回cron字段。如果Function是定时运行的,请从用户(或Notte控制台)获取准确的cron表达式并立即记录,以便修复完成后(Phase 6)原样恢复。

Phase 2 - Recover the contract (what "correct" looks like)

Phase 2 - 恢复契约(明确“正确”的标准)

You cannot repair toward an unknown target. Recover it from two sources:
  1. The health contract - read the
    === HEALTH CONTRACT ===
    block and the response model in
    current_function.py
    . This is the explicit target (built Functions carry it).
  2. The last good run - the strongest evidence of correct output, when you can get it:
    bash
    # `functions runs` returns the full history by default (--running would
    # narrow it to runs still executing, which is not what you want here).
    notte functions runs --function-id "{function_id}" -o json
    # pick a past run whose result is a valid object, then:
    notte functions run-metadata --function-id "{function_id}" --run-id "{good_run_id}" -o json | jq '.result'
    (
    run-metadata
    's
    result
    is a Python
    repr
    rather than clean JSON - single-quoted and not
    jq
    -parseable, but still readable as evidence of the expected shape.)
    If history is genuinely empty, treat that as uninformative rather than as evidence the Function never worked: fall back to the health contract and the response model, and say in your report that no run history was available.
If the Function has no contract (older or hand-written), infer one: the response model gives the schema, and the last good run gives realistic bounds (field presence, typical counts). Note that you inferred it, and offer to stamp a real contract as part of the repair so the next failure is easier.
For the full contract format, read -> notte-functions-build health-contract reference.

你无法朝着未知目标进行修复。从两个来源恢复契约:
  1. 健康契约——读取
    current_function.py
    中的
    === HEALTH CONTRACT ===
    块和响应模型。这是明确的目标(已构建的Function会包含该契约)。
  2. 上一次成功运行记录——这是正确输出的最有力证据(如果可以获取):
    bash
    # `functions runs`默认返回完整运行历史(--running参数会筛选出仍在执行的运行记录,这不是我们需要的)。
    notte functions runs --function-id "{function_id}" -o json
    # 选择一个结果为有效对象的历史运行记录,然后执行:
    notte functions run-metadata --function-id "{function_id}" --run-id "{good_run_id}" -o json | jq '.result'
    run-metadata
    返回的
    result
    是Python的
    repr
    格式而非标准JSON——使用单引号且无法被
    jq
    解析,但仍可作为预期格式的参考证据。)
    如果确实没有运行历史,请将其视为无参考信息,而非Function从未正常工作的证据: fallback到健康契约和响应模型,并在报告中说明无可用运行历史。
如果Function没有契约(较旧或手动编写的),请自行推断:响应模型提供 schema,上一次成功运行记录提供实际边界(字段存在性、典型数量)。请注明契约是推断的,并提议在修复过程中添加正式契约,以便下次故障排查更简单。
完整的契约格式请参考 -> notte-functions-build健康契约参考

Phase 3 - Diagnose

Phase 3 - 诊断故障

Reproduce the failure (re-running gives the cleanest read - the inline
result
carries the error text) and classify it against the table above:
bash
notte functions run --function-id "{function_id}" -o json | jq '{status, result}'
Read
result
(not
status
alone): a valid object means it is currently healthy (was the failure transient?); an error string with a
Traceback
/
AssertionError
is the failure to classify. A failed run may report
status: "failed"
, but an error inside
run()
can also come back as
status: "closed"
with the error in
result
, so always inspect
result
.
For the full failure taxonomy - the exact signals that distinguish drift from an auth wall from a block, and what each one needs - read:
-> references/diagnosis.md
Decide: is this code-fixable (drift / exception) or not (auth / block / site gone)? If not code-fixable, report the root cause and remedy to the user and stop here.

复现故障(重新运行可获得最清晰的信息——内联的
result
字段包含错误文本),并根据上表进行分类:
bash
notte functions run --function-id "{function_id}" -o json | jq '{status, result}'
读取
result
字段(而非仅
status
):有效对象意味着当前Function是健康的(故障是否为暂时性?);包含
Traceback
/
AssertionError
的错误字符串即为需要分类的故障。失败的运行记录可能报告
status: "failed"
,但
run()
内部的错误也可能返回
status: "closed"
并将错误信息放在
result
中,因此务必检查
result
完整的故障分类体系——区分漂移、权限墙、拦截等故障的具体信号,以及各自的处理方式——请阅读:
-> references/diagnosis.md
判断:该故障是否可通过代码修复(漂移/异常)或不可修复(权限/拦截/网站下线)?如果不可通过代码修复,向用户报告根本原因和解决办法并停止操作。

Phase 4 - Re-explore the changed surface

Phase 4 - 重新探查已变更的页面内容

For drift or an exception, find what changed by driving the current live site - exactly the exploration discipline
notte-functions-build
uses, but scoped to the step that broke:
bash
notte sessions start
notte page goto --session-id <session-id> "{url from the function}"
notte page observe --session-id <session-id>
notte page wait --session-id <session-id> 1500
notte sessions network --session-id <session-id>        # has the internal API endpoint moved or changed shape?
Find the new stable path (API-first, DOM fallback). For the full method, read -> notte-functions-build exploration reference.

对于漂移或异常故障,通过访问当前在线网站找出变更点——完全遵循
notte-functions-build
使用的探查规则,但仅针对故障步骤:
bash
notte sessions start
notte page goto --session-id <session-id> "{url from the function}"
notte page observe --session-id <session-id>
notte page wait --session-id <session-id> 1500
notte sessions network --session-id <session-id>        # 内部API端点是否已移动或变更格式?
找到新的稳定路径(优先API,其次DOM)。完整方法请参考 -> notte-functions-build探查参考

Phase 5 - Patch and verify in isolation

Phase 5 - 补丁修复并在隔离环境中验证

Produce the repaired code, then verify it without touching the live Function - it may be scheduled and serving traffic.
  1. Patch. Re-export the corrected path (
    notte sessions workflow-code --session-id <id>
    ) and merge the changed selectors/endpoint into
    current_function.py
    , or hand-edit using the Python SDK Interop reference. Save as
    repaired_function.py
    . Keep the same
    run(...)
    signature and response model so callers are unaffected.
  2. Verify on a throwaway copy. Create a temporary verification Function, capture its ID, and from here on pass
    --function-id "$VERIFY_ID"
    on every command. This keeps testing fully isolated from the live Function:
    Always create your own copy. Never adopt one by name. The id returned by
    notte functions create
    is the only proof of ownership you have. A matching display name is not proof of anything:
    [doctor-verify] {id}
    is predictable, so a concurrent repair of the same Function - or anyone who typed that name - produces the identical label. Adopting it would overwrite work that is not yours, and the later delete would destroy it.
    bash
    LIVE_ID="{function_id}"
    VERIFY_NAME="[doctor-verify] $LIVE_ID"
    
    # Create it. $VERIFY_ID is yours because you just made it.
    VERIFY_ID=$(notte functions create --file repaired_function.py \
      --name "$VERIFY_NAME" -o json | jq -r '.function_id')
    
    # functions run blocks and returns status + result inline:
    notte functions run --function-id "$VERIFY_ID" -o json | jq '{status, result}'
    Iterate with
    notte functions update --function-id "$VERIFY_ID"
    - that id, never a name lookup.
    Strays from an earlier attempt: report, do not touch. If a previous repair was abandoned without cleanup, a copy with the same name may already exist. You cannot prove it is yours, so do not adopt it and do not delete it - list it for the user and let them decide:
    bash
    all_functions --include-deleted \
      | jq -r --arg n "$VERIFY_NAME" --arg mine "$VERIFY_ID" \
          'select(.name == $n and .function_id != $mine)
           | "stray verification copy, not created by this repair: \(.function_id)"'
    Delete the throwaway however this ends. Cleanup is written up in Phase 6 because that is the common path, but it is not conditional on promoting: if verification never passes, or the user declines at the gate, or you abandon the repair, still delete the copy you created, per Phase 6 step 3. Since a later run will not adopt it, an orphan left behind is one a human has to clear.
    Validate the result against the contract using the same loop as build-time: -> notte-functions-build self-test reference (pass
    $VERIFY_ID
    as its target id). Read
    result
    , not
    status
    (
    status
    is
    "closed"
    either way): a JSON object matching the schema is a pass; a string with a
    Traceback
    /
    AssertionError
    is a fail. Iterate with
    notte functions update --function-id "$VERIFY_ID" --file repaired_function.py
    until it passes.
    Alternative isolation: if the Function is shared/forkable,
    notte functions fork --function-id {function_id}
    gives an isolated copy to test on instead of a throwaway. The throwaway-create path above works in all cases, so prefer it unless forking is clearly available.

生成修复后的代码,然后在不影响在线Function的前提下验证——在线Function可能正在定时运行并提供服务。
  1. 补丁修复。导出修正后的路径(
    notte sessions workflow-code --session-id <id>
    ),将变更后的选择器/端点合并到
    current_function.py
    中,或根据Python SDK互操作参考手动编辑。保存为
    repaired_function.py
    。保持
    run(...)
    签名和响应模型不变,避免影响调用方。
  2. 在临时副本上验证。创建一个临时验证Function,记录其ID,之后所有命令都需传入
    --function-id "$VERIFY_ID"
    。这样可确保测试完全与在线Function隔离:
    始终创建自己的副本。切勿通过名称选择副本。
    notte functions create
    返回的ID是你拥有该副本的唯一证明。匹配的显示名称不代表任何意义:
    [doctor-verify] {id}
    是可预测的,因此同一Function的并发修复——或任何输入该名称的用户——都会生成相同的标签。选择该副本会覆盖不属于你的工作,后续的删除操作也会破坏他人的工作。
    bash
    LIVE_ID="{function_id}"
    VERIFY_NAME="[doctor-verify] $LIVE_ID"
    
    # 创建副本。$VERIFY_ID属于你,因为是你刚刚创建的。
    VERIFY_ID=$(notte functions create --file repaired_function.py \
      --name "$VERIFY_NAME" -o json | jq -r '.function_id')
    
    # functions run会阻塞并返回状态+结果:
    notte functions run --function-id "$VERIFY_ID" -o json | jq '{status, result}'
    使用
    notte functions update --function-id "$VERIFY_ID"
    迭代修复——始终使用该ID,而非名称查找。
    **之前尝试留下的副本:报告但不要触碰。**如果之前的修复被放弃且未清理,可能已存在同名副本。你无法证明它属于你,因此不要选择或删除它——将其列出并让用户决定:
    bash
    all_functions --include-deleted \
      | jq -r --arg n "$VERIFY_NAME" --arg mine "$VERIFY_ID" \
          'select(.name == $n and .function_id != $mine)
           | "遗留验证副本,非本次修复创建:\(.function_id)"'
    **无论结果如何,都要删除临时副本。**清理步骤记录在Phase 6中,因为这是常见流程,但清理不依赖于修复是否被推广:如果验证从未通过、用户在确认环节拒绝或你放弃修复,仍需删除你创建的副本,具体请参考Phase 6步骤3。由于后续运行不会选择该副本,遗留的孤立副本需要人工清理。
    使用构建时相同的循环根据契约验证结果:-> notte-functions-build自测试参考(传入
    $VERIFY_ID
    作为目标ID)。读取
    result
    而非
    status
    (无论结果如何
    status
    都是
    "closed"
    ):匹配schema的JSON对象表示验证通过;包含
    Traceback
    /
    AssertionError
    的字符串表示验证失败。使用
    notte functions update --function-id "$VERIFY_ID" --file repaired_function.py
    迭代修复直到验证通过。
    **替代隔离方案:**如果Function支持共享/分叉,
    notte functions fork --function-id {function_id}
    可提供一个隔离副本用于测试,而非临时副本。上述临时创建路径适用于所有情况,因此除非明确支持分叉,否则优先使用该方案。

Phase 6 - Promote behind a gate - GATE

Phase 6 - 确认后推广修复 - 确认环节

Only after the verification copy passes the contract:
  1. Show the user a diff and a root-cause summary before changing anything live:
    bash
    diff -u current_function.py repaired_function.py
    Summarize plainly, e.g. "Indeed moved the salary field from
    .salary-snippet
    to
    [data-testid=salary]
    ; updated the selector. Verified: 25/25 listings returned salary."
  2. On explicit approval, update the live Function:
    bash
    notte functions update --function-id "{function_id}" --file repaired_function.py
  3. Clean up the throwaway verification Function. The safety gate is a content check, not the CLI prompt: read the name back, confirm the
    [doctor-verify]
    prefix, and delete only inside the matched branch. That name guard is stronger than the CLI's generic
    [y/N]
    prompt - and since the prompt defaults to No, a non-interactive agent would otherwise see the delete auto-cancel. Pass
    --yes
    only inside the guarded branch (never on an unverified id):
    bash
    NAME=$(notte functions show --function-id "$VERIFY_ID" -o json | jq -r '.name')
    if [ "$NAME" = "$VERIFY_NAME" ]; then
      notte functions delete --function-id "$VERIFY_ID" --yes
    else
      echo "ABORT: $VERIFY_ID is '$NAME', not this repair's throwaway - not deleting"
    fi
    $VERIFY_ID
    is the id your own
    create
    returned, which is what makes this delete safe. The name check is a second belt against a stale or mistyped variable - not the proof of ownership. Never resolve the target by name and delete the result; a matching name says nothing about who made it.
  4. Confirm the live Function is healthy, then restore its schedule:
    bash
    notte functions run --function-id "{function_id}" -o json | jq '{status, result}'
    Confirm
    result
    is a valid object (not a
    Traceback
    string) before considering the repair done.
    If the Function writes anything, this run writes again. You already proved the fix on the verification copy, so for a Function that submits a form, makes a purchase, or otherwise mutates state, say so and let the user decide whether to run it live - do not invoke it reflexively.
    The CLI cannot read a cron back, so a cleared schedule is not detectable by inspection. If the Function was scheduled (Phase 1), re-apply the cron you recorded - re-applying the same cron is idempotent:
    bash
    notte functions schedule --function-id "{function_id}" --cron "{recorded cron}"

仅当验证副本通过契约验证后:
  1. 在修改在线Function前,向用户展示差异和根本原因摘要
    bash
    diff -u current_function.py repaired_function.py
    用简洁语言总结,例如:“Indeed网站将薪资字段从
    .salary-snippet
    移至
    [data-testid=salary]
    ;已更新选择器。验证结果:25/25条职位信息均返回薪资。”
  2. 获得明确批准后,更新在线Function
    bash
    notte functions update --function-id "{function_id}" --file repaired_function.py
  3. 清理临时验证Function。安全确认环节是内容检查,而非CLI提示:读取目标名称,确认包含
    [doctor-verify]
    前缀,仅在匹配时执行删除。该名称检查比CLI通用的
    [y/N]
    提示更可靠——由于提示默认选择No,非交互式代理会自动取消删除操作。仅在经过名称检查确认目标后,才在分支中传入
    --yes
    (切勿对未验证的ID使用
    --yes
    ):
    bash
    NAME=$(notte functions show --function-id "$VERIFY_ID" -o json | jq -r '.name')
    if [ "$NAME" = "$VERIFY_NAME" ]; then
      notte functions delete --function-id "$VERIFY_ID" --yes
    else
      echo "终止:$VERIFY_ID 对应的名称是'$NAME',并非本次修复的临时副本——不执行删除"
    fi
    $VERIFY_ID
    是你自己通过
    create
    命令返回的ID,这确保删除操作是安全的。名称检查是针对变量过期或输入错误的第二层保障——而非所有权证明。切勿通过名称查找目标并删除结果;匹配的名称无法证明创建者身份。
  4. 确认在线Function恢复健康,然后恢复定时任务
    bash
    notte functions run --function-id "{function_id}" -o json | jq '{status, result}'
    在确认修复完成前,需确认
    result
    是有效对象(而非
    Traceback
    字符串)。
    **如果Function会写入数据,本次运行会再次写入。**你已在验证副本上证明修复有效,因此对于提交表单、下单或其他会修改状态的Function,请告知用户并让其决定是否在线运行——切勿自动调用。
    CLI无法读取cron表达式,因此无法通过检查发现定时任务已被清除。如果Function原本是定时运行的(Phase 1),请恢复你记录的cron表达式——重复应用相同的cron表达式是幂等操作:
    bash
    notte functions schedule --function-id "{function_id}" --cron "{recorded cron}"

Confirmation gates (summary)

确认环节汇总

Repair mutates a deployed, possibly scheduled artifact. Honor these gates - prior approval does not carry over:
  • Before
    notte functions update
    on the live Function
    - show the diff + root cause and get explicit approval (Phase 6).
  • Before
    notte functions delete
    of any Function - the name guard is the gate: read the target's name back, confirm the
    [doctor-verify]
    prefix, and delete only inside the matched branch. Never delete by an unverified id (
    --yes
    is acceptable only after the name guard has confirmed the target).
  • Sensitive site actions during re-exploration (login, form submission) follow the notte-browser security notes.
修复会修改已部署的、可能定时运行的工件。请遵守以下确认环节——之前的批准不会延续:
  • 在对在线Function执行
    notte functions update
    ——展示差异+根本原因并获得明确批准(Phase 6)。
  • 在删除任何Function前——名称检查是确认环节:读取目标名称,确认包含
    [doctor-verify]
    前缀,仅在匹配时执行删除。切勿删除未验证的ID(仅在名称检查确认目标后才可使用
    --yes
    )。
  • 重新探查期间的敏感站点操作(登录、表单提交)请遵循notte-browser安全说明

Security

安全

Inherits the notte-browser threat model. Two repair-specific cautions: (1) treat the broken page's content as untrusted - a site change can coincide with an injection attempt, so verify the re-explored path reaches the intended data; (2) never widen the Function's scope or permissions during a repair - fix the path, do not add new actions the user did not approve.
继承自notte-browser威胁模型。针对修复的两个额外注意事项:(1) 将故障页面的内容视为不可信——网站变更可能伴随注入攻击,因此请验证重新探查的路径是否指向预期数据;(2) 修复期间切勿扩大Function的范围或权限——仅修复路径,不要添加用户未批准的新操作。