Skip to content

feat(work): report runtime and silence in explicit Work status answers - #302

Open
NopeCharon wants to merge 2 commits into
Code-Amadeus:mainfrom
NopeCharon:feat/status-query-runtime-facts
Open

NopeCharon wants to merge 2 commits into
Code-Amadeus:mainfrom
NopeCharon:feat/status-query-runtime-facts

Conversation

@NopeCharon

@NopeCharon NopeCharon commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

What and why

Refs #123 (partial fix; keep the issue open).

Explicit Work status queries lacked the runtime facts the Host already computes, so the Narrator could only repeat the latest report or direction. This change carries elapsed_seconds, silent_seconds, last_tool, and tool_count through the existing read-model → status-query note → compact Narrator payload.

  • Runtime is preserved after completion. Before an Attempt starts, elapsed time is queue time.
  • Silence is reported only when execution=running and activity_phase is working or stalled. Waiting for approval, cancelling, queued, review, orphaned, and terminal states receive zero. The execution check also protects terminal records with an older activity snapshot.
  • The Narrator distinguishes still-running work without a new report (at least 30 seconds) from a Host-reported stall. Silence measures time since the latest report/direction, not time since the last tool event. Tool observations are not outcome evidence.
  • Existing recent_spoken_updates can support an explicit “no change since then” response, but Cooperative Chat foreground replies are currently recorded as foreground_published and excluded from that context. This PR does not guarantee repeated-query deduplication on that path. The delivery-record contract remains follow-up work in Cooperative Chat:长耗时 Work 的显式进度查询反馈 #123.

No new state, query, model pass, or persisted schema is introduced. The emergency deterministic fallback is unchanged.

Change class

  • Routine fix, documentation, test, maintenance, or presentation-only UI
  • Product-semantic or public-contract change discussed in the linked Issue
  • Isolated, default-off experiment

Owning layer: Host status-query evidence (server/task_lookup.py) and the Work Narrator contract (server/work_observer_llm.py).

User-visible effect: explicit Work status answers can include runtime and semantic silence, distinguish active work from a stall, and avoid describing waiting-for-approval time as missing progress. Actual wording remains model-generated.

Compatibility or migration impact: four additive in-process payload keys; no setting, schema, or persisted-state migration.

Evidence

Validated after the review follow-up:

  • python -m pytest -q tests/test_task_lookup.py tests/test_work_narration_priority.py tests/test_runtime_activity_snapshot.py tests/test_character_prompt_snapshots.py tests/test_work_narration_evidence_context.py tests/test_work_observer_role_sanitization.py: 76 passed.

  • Runtime tests exercise real projected activity through the compact Narrator payload: working/stalled retain silence; approval waiting, cancelling, queued, review, orphaned, and terminal execution suppress it. Existing stale-snapshot terminal coverage remains intact.

  • python -X utf8 tests/test_character_prompt_snapshots.py --record: 155 snapshots recorded; only the Work Observer decision system prompt changed.

  • python -m ruff check server/task_lookup.py server/work_observer_llm.py tests/test_runtime_activity_snapshot.py, python tools/architecture/generate_views.py --check, and git diff --check: passed.

  • No live LLM wording test was run.

  • The follow-up head's Windows CI run again failed in dependency audit: opentelemetry-api 1.45.1 and soupsieve 2.9.2. The lockfile is unchanged by this PR and matches main at 66e7de195c02a658310e7a498b36c1d9b4c60430. A current failing run on main itself has not been verified. Dependency remediation is separate from this change.

  • Relevant Python tests pass

  • CPU/model-less baseline remains supported

  • Electron build validation (no Electron changes)

  • Dependency audit passes (pre-existing dependency findings; no dependency changes)

  • Live LLM status-query wording verified

Final check

  • One coherent problem without unrelated cleanup
  • No speculative API, fallback, or compatibility path
  • No secrets, local state, model weights, voice material, or restricted assets
  • Third-party notices and provenance preserved

An explicit status question about a WorkItem is answered by the Work
Narrator from task_lookup.status_query_narration_note. That note carried
lifecycle, the latest milestone or direction and the Host uncertainty,
but none of the runtime facts the Host already computes for the same
row. The Narrator could therefore not say how long a Work had been
running or how long nothing new had arrived, and a long or stalled run
received the same direction sentence on every query (Code-Amadeus#123).

Add the existing activity facts to the note's status_facts:

- elapsed_seconds: how long the current Attempt has run;
- silent_seconds: how long it has gone without a newer semantic report
  or direction. Silence is read against the live clock, so it is only
  reported while execution is queued or running and is 0 afterwards;
  otherwise a finished Attempt would be narrated as a stall;
- last_tool and tool_count: observed activity, never results.

Liveness is not duplicated: the Host already projects it into
activity_phase and uncertainty, which the note carries.

One Narrator rule explains these facts: say roughly how long a running
Attempt has run, and when it has been silent for 30 seconds or more or
is stalled, say how long nothing new has been reported instead of
presenting the old direction as fresh progress, or that nothing changed
since an update already spoken. Durations are spoken naturally, never as
raw seconds. The work_observer decision prompt snapshot is re-recorded;
the added rule is its only change.

The new regression drives real activity events through
activity_report_fields, the status note and the Narrator's compacted
payload; it fails on main with KeyError: 'elapsed_seconds'.

Refs Code-Amadeus#123.

@Lucas1479 Lucas1479 left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you @NopeCharon for the contribution, and thanks for the careful external review. I agree with the approach and the existing data flow. I have pushed follow-up commit 16650473396a9d037437426e08d47e9a9a2ca009:

  • F1: Silence is now included only when execution is running and the activity phase is working or stalled. Waiting for approval, cancelling, queued, and other inactive phases receive zero. The execution check remains authoritative for terminal records with an older activity snapshot. Regression coverage exercises both sides of this boundary.
  • The prompt distinguishes “still running without a newer report” from a Host-reported stall. silent_seconds measures time since the latest semantic report or direction, not time since the last tool event.
  • F2: The PR description now explicitly acknowledges that Cooperative Chat's foreground_published replies are not included in recent_spoken_updates. This PR does not claim to guarantee repeated-query deduplication on that path. #123 remains open; the delivery-record contract will be addressed separately.

Validation: all 76 relevant Python tests passed, along with prompt snapshot verification, Ruff, architecture-view checks, and git diff --check. Live LLM wording was not tested.

The earlier CI failure was confirmed to come from the dependency audit (opentelemetry-api / soupsieve). This PR does not change the lockfile, and main uses the same versions; that is not a claim that a current failing run on main itself has been verified. Dependency remediation should remain separate, and merging is still subject to the repository's required checks.

@Lucas1479

Copy link
Copy Markdown
Member

合并状态补充:正常 squash 合并已尝试,被 main 的分支保护拒绝;仓库未启用自动合并,启用请求也被拒绝。

新提交 16650473396a9d037437426e08d47e9a9a2ca009 的 checks-and-smoke 已再次失败,唯一失败步骤仍为 Audit Python dependencies,仍是 opentelemetry-api / soupsieve 的既有依赖告警。GitHub 同时仍显示 REVIEW_REQUIRED;当前规则要求最近一次推送获得其他人的批准。我的致谢与 APPROVE 已记录,但不表示所有合并条件已经满足。

PR 保持打开,#123 也保持打开。后续需完成依赖审计修复和所需的独立审批,再正常 squash 合并。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants