docs: roadmap consolidation, staleness refresh, settled design cases - #38
docs: roadmap consolidation, staleness refresh, settled design cases#38t41372 wants to merge 3 commits into
Conversation
The canonical roadmap now lives in issue #27 (which declared itself the replacement). The committed page had already drifted (still listed the first PyPI release as pending) — a second source of truth we don't want to maintain. The docs nav now links to the issue directly, same as the existing external Releasing entry.
Dependency Review✅ No vulnerabilities or license issues or OpenSSF Scorecard issues found.Scanned FilesNone |
📝 WalkthroughWalkthroughThis PR documents diarization behavior, clarifies normative specification contracts, adds release-pipeline and streaming-tuning design cases, updates documentation navigation, and changes installation guidance to published package commands. ChangesDocumentation and design updates
Estimated code review effort: 2 (Simple) | ~15 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/feat_plan/release-pipeline-redesign.md`:
- Around line 72-94: The fenced flow block in the release pipeline redesign doc
is missing a language tag, which triggers Markdownlint MD040. Update the opening
fence for that block to use a text language tag so the existing content remains
unchanged while satisfying the lint rule; this applies to the flow diagram
section near the version/publish steps.
In `@docs/for_app_dev/discover_and_use.md`:
- Around line 80-90: Update the diarization docs in the example around
result.segments and the surrounding prose to account for the always_on
exception: `segment.speaker` should not be described as `None` whenever
diarization was not requested, since always_on engines may still populate
speaker labels. Adjust the inline comment and the explanatory paragraph to say
speaker labels are present when supported by the engine even without an explicit
request, while `None` still means not attributed. Use the `segment.speaker` and
`word.speaker` references in that section to keep the wording aligned.
In `@docs/for_app_dev/errors.md`:
- Around line 53-55: The error example for UnsupportedFeatureError currently
suggests that .details is commonly available, which is misleading. Update the
snippet around UnsupportedFeatureError to either use an example that explicitly
populates details through the relevant constructor path, or remove the
exc.details line and keep only the fields that are actually expected such as
exc.param and exc.hint.
In `@docs/for_app_dev/streaming.md`:
- Around line 58-61: Update the streaming documentation paragraph around
RuntimeParams and event.speaker to include the always_on exception: clarify that
event.speaker stays None when diarization was not requested or is unsupported,
except for always_on engines which may emit speaker labels without an explicit
diarization request. Keep the wording aligned with the existing
streaming.diarization and DIARIZE explanation.
In `@docs/installation.md`:
- Around line 43-50: The “Install from source” section is ambiguous because the
current `pip install "standard-asr @ git+..."` example installs a remote
snapshot rather than a local editable checkout. Update the `installation.md`
guidance to either describe the contributor workflow using a local clone with an
editable install via the project’s setup instructions, or rename the section to
clearly state that it is a remote Git install. Keep the wording aligned with the
section title and the install example so readers understand whether they are
working from a local checkout or a published repository snapshot.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 9cc6c743-bb30-41b0-ac94-c5765389b8b3
📒 Files selected for processing (13)
CHANGELOG.mdREADME.mddocs/feat_plan/release-pipeline-redesign.mddocs/feat_plan/streaming-cadence-and-tuning.mddocs/for_app_dev/discover_and_use.mddocs/for_app_dev/errors.mddocs/for_app_dev/streaming.mddocs/for_asr_dev/plugin_entrypoints.mddocs/installation.mddocs/quickstart.mddocs/roadmap.mddocs/spec/specification.mdmkdocs.yml
💤 Files with no reviewable changes (1)
- docs/roadmap.md
c5940d2 to
0bdf982
Compare
0bdf982 to
3b4fc54
Compare
There was a problem hiding this comment.
Actionable comments posted: 7
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
docs/spec/specification.md (1)
1253-1262: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick winSeparate global streaming capabilities from mode-scoped capabilities.
The introduction says all listed nodes live under
capabilities.streaming.*, butstreaming_inputandstreaming_outputare defined elsewhere as top-level global capabilities. Clarify the table so consumers do not serialize or query these axes ascapabilities.streaming.streaming_inputandcapabilities.streaming.streaming_output.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@docs/spec/specification.md` around lines 1253 - 1262, 更新该 capability 表及其引导文字,明确区分顶层全局的 streaming_input 和 streaming_output 与 capabilities.streaming.* 下的模式级节点;将前两项标注为顶层路径,避免消费者将其序列化或查询为 capabilities.streaming.streaming_input/streaming_output,并保留其余 streaming.* 节点不变。
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@docs/feat_plan/release-pipeline-redesign.md`:
- Around line 67-75: Update the release-pipeline heading and surrounding summary
to describe a single release pipeline rather than “one human action,” while
preserving the documented merge, workflow dispatch, and dev-bump PR steps.
- Around line 90-103: Update the release-pipeline description around “create
GitHub Release” and “Why publish-PyPI-before-GitHub-Release” to avoid claiming
tag and release creation are atomic. Document that gh release create may leave a
tag when release creation fails, and add an explicit retry/reconciliation path
for the tag-created/release-failed state.
In `@docs/feat_plan/streaming-cadence-and-tuning.md`:
- Line 140: Rewrite the sentence beginning with “#33's probe set” so it refers
to “the probe set for issue `#33`” or equivalent, ensuring the line no longer
begins with a hash that Markdownlint interprets as a heading.
- Around line 96-103: Revise the StreamingCapabilities.output_latency
declaration to represent non-contiguous supported values, including 80–1200 ms
in 80 ms increments and the standalone 2400 ms value. Extend the constraint
model with an explicit discrete-values or exception mechanism, and ensure
supports(), canonical JSON, and wire serialization preserve the exact set
without advertising unsupported intermediate values; do not rely on snapping.
In `@docs/spec/specification.md`:
- Around line 950-958: The error-event contract must not permit logging raw
exception text. Update the adjacent error-logging rule to require redacted,
allowlisted structured fields only, excluding paths, URLs, credentials, and
other untrusted exception details, while preserving the client payload’s removal
of human-readable error details.
- Around line 683-691: Clarify the speaker inheritance model in the
specification so Word.speaker=None cannot simultaneously mean inheritance and
explicit unknown attribution. Define a distinct representation for an explicitly
unknown word speaker while preserving None as the inheritance marker, and update
the related None semantics and segment-speaker synthesis rules to use that
representation consistently.
- Line 135: Update Example E to align with the v1 streaming contract: describe
incompatible wire sample rates as rejected by
EngineBase.ensure_stream_format_supported when standard-layer streaming
resampling is unavailable, rather than requiring 16 kHz→24 kHz resampling.
Alternatively, explicitly label the resampling and missing-[audio] failure
behavior as future standard-layer streaming behavior, while preserving it for
the batch transcribe path.
---
Outside diff comments:
In `@docs/spec/specification.md`:
- Around line 1253-1262: 更新该 capability 表及其引导文字,明确区分顶层全局的 streaming_input 和
streaming_output 与 capabilities.streaming.* 下的模式级节点;将前两项标注为顶层路径,避免消费者将其序列化或查询为
capabilities.streaming.streaming_input/streaming_output,并保留其余 streaming.* 节点不变。
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: 64de8bf0-5e40-4752-bacf-660666b3dc49
📒 Files selected for processing (13)
CHANGELOG.mdREADME.mddocs/feat_plan/release-pipeline-redesign.mddocs/feat_plan/streaming-cadence-and-tuning.mddocs/for_app_dev/discover_and_use.mddocs/for_app_dev/errors.mddocs/for_app_dev/streaming.mddocs/for_asr_dev/plugin_entrypoints.mddocs/installation.mddocs/quickstart.mddocs/roadmap.mddocs/spec/specification.mdmkdocs.yml
💤 Files with no reviewable changes (1)
- docs/roadmap.md
🚧 Files skipped from review as they are similar to previous changes (9)
- README.md
- CHANGELOG.md
- docs/for_app_dev/errors.md
- docs/quickstart.md
- docs/for_app_dev/discover_and_use.md
- docs/for_app_dev/streaming.md
- mkdocs.yml
- docs/for_asr_dev/plugin_entrypoints.md
- docs/installation.md
| **One pipeline, one human action, fully automatic, ordered by | ||
| irreversibility.** The GitHub Release is demoted from *trigger* to *final | ||
| output*; the TestPyPI rehearsal is promoted from *separate manual dry-run* to | ||
| *inline stage of every release*. | ||
|
|
||
| ```text | ||
| [human] merge chore(release): vX.Y.Z PR (version + CHANGELOG entry) | ||
| [human] press workflow_dispatch ← the only trigger; version read | ||
| │ from pyproject.toml on main |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Reconcile the “one human action” claim with the documented flow.
This section shows at least two human actions—merging the release PR and dispatching the workflow—and step 8 later requires merging the dev-bump PR. Replace “one human action” with a precise description such as “one release pipeline” to avoid contradicting the runbook.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/feat_plan/release-pipeline-redesign.md` around lines 67 - 75, Update the
release-pipeline heading and surrounding summary to describe a single release
pipeline rather than “one human action,” while preserving the documented merge,
workflow dispatch, and dev-bump PR steps.
| ├─ 7. create GitHub Release: gh release create vX.Y.Z --target <sha> | ||
| │ (creates tag + release atomically; notes = the CHANGELOG section) | ||
| └─ 8. open follow-up PR: bump pyproject to X.Y.(Z+1).dev0 + `uv lock` | ||
| (maintainer merges; CI validates it like any PR) | ||
| ``` | ||
|
|
||
| ### 2.1 Why publish-PyPI-before-GitHub-Release | ||
|
|
||
| The GitHub Release is the only step that permanently burns a tag name (once | ||
| immutable releases return). Placed last, its failure-downstream is empty: | ||
| `gh release create` failing means PyPI is live and the fix is a retry of one | ||
| idempotent-ish step — nothing is burned, nothing is inconsistent for longer | ||
| than the retry. It also makes the announcement follow the fact: no window | ||
| where GitHub says "released" but `pip install` fails. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the target file and nearby references
git ls-files docs/feat_plan/release-pipeline-redesign.md
printf '\n--- file excerpt ---\n'
sed -n '1,220p' docs/feat_plan/release-pipeline-redesign.md
printf '\n--- search for recovery / retry / reconciliation / tag-created / release-failed ---\n'
rg -n "retry|reconcil|tag-created|release-failed|gh release create|immutable releases|burns a tag|PyPI-before-GitHub-Release|follow-up PR|release" docs/feat_plan/release-pipeline-redesign.mdRepository: standard-voice/standard_asr
Length of output: 17018
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Check the GitHub CLI docs wording around tag creation and release creation.
python3 - <<'PY'
import urllib.request, re
url = "https://cli.github.com/manual/gh_release_create"
html = urllib.request.urlopen(url, timeout=20).read().decode("utf-8", "replace")
for needle in [
"automatically create",
"create a new release",
"create a tag",
"If the tag does not exist",
"the tag will be created",
]:
idx = html.lower().find(needle.lower())
print(f"\n=== {needle} ===")
if idx == -1:
print("not found")
else:
start = max(0, idx - 300)
end = min(len(html), idx + 700)
print(re.sub(r"<[^>]+>", " ", html[start:end]))
PYRepository: standard-voice/standard_asr
Length of output: 2759
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Look for any mention of explicit recovery for a tag-created/release-failed state elsewhere in the repo.
rg -n "tag.*release|release.*tag|reconcile|recovery|retry|idempotent|burns a tag|atomic|GitHub Release|gh release create" .Repository: standard-voice/standard_asr
Length of output: 7959
Do not call tag creation and release creation atomic. gh release create may leave a tag behind if release creation fails, so the zero-burn recovery story needs an explicit retry/reconciliation path for a tag-created/release-failed state.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/feat_plan/release-pipeline-redesign.md` around lines 90 - 103, Update
the release-pipeline description around “create GitHub Release” and “Why
publish-PyPI-before-GitHub-Release” to avoid claiming tag and release creation
are atomic. Document that gh release create may leave a tag when release
creation fails, and add an explicit retry/reconciliation path for the
tag-created/release-failed state.
| **D1 — Declaration: `StreamingCapabilities.output_latency` node.** | ||
| `mode: "fixed" | "configurable" | "tiered" | "none"` (default `none` — degrade | ||
| to unknown, never false precision), with constraint payload: | ||
| `points_ms: list[int]` (tiered — non-empty, sorted), `range_ms: {min, max, | ||
| step?}` (configurable — `step` optional, for the verified 80 ms-stepped dials), | ||
| and `typical_ms: int | None` (all modes except `none`; the default/expected | ||
| operating point). Lives in **capabilities** because it gates the tuning param | ||
| (D3) — and it flows into `supports()`, canonical JSON, and the wire for free. |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Represent non-contiguous latency values explicitly.
The documented Voxtral range supports 80–1200 ms in 80 ms steps plus a standalone 2400 ms value. range_ms: {min, max, step} cannot represent that set without advertising unsupported values or omitting 2400 ms. Add an explicit discrete-values/exception mechanism, or revise the declaration model before implementation; snapping does not fix an inaccurate capability declaration.
Also applies to: 112-120
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/feat_plan/streaming-cadence-and-tuning.md` around lines 96 - 103, Revise
the StreamingCapabilities.output_latency declaration to represent non-contiguous
supported values, including 80–1200 ms in 80 ms increments and the standalone
2400 ms value. Extend the constraint model with an explicit discrete-values or
exception mechanism, and ensure supports(), canonical JSON, and wire
serialization preserve the exact set without advertising unsupported
intermediate values; do not rely on snapping.
| 说话人分离("谁说了什么")经 [§Runtime 参数 3.4](#runtime-parameters) 的 `diarization` marker 请求,能力声明于 `capabilities.<mode>.diarization`([§能力系统 3.2](#capabilities))。结果语义(normative): | ||
|
|
||
| - **`Segment.speaker`(权威)+ `Word.speaker`(可选细化)。继承规则**:`Word.speaker` 为 `None` 时继承所在段的 `Segment.speaker`;非 `None` 时在词级**覆盖**段级值(混合说话人段的词级细化)。**不**加顶层 `speakers[]` roster(YAGNI,需要时 additive)。 | ||
| - **`None` 语义(TR.1 重申)**:diarization **激活**时 `speaker=None` = "引擎无法判定该段/词的说话人"(显式的「不知道」);未请求时 = 不适用。应用判「引擎是否支持/做了 diarization」MUST 看 capability,MUST NOT 看字段 null(TR.1 null 规则;always-on 豁免见下,使字段 null 判定更加不可靠)。 | ||
| - **段级 speaker 合成(标准层,单一钉死规则)**:当 `Segment.speaker is None` 而其 `words` 携带非 `None` speaker 时,标准层合成段级 speaker。规则**唯一且钉死**:**按词数多数决;平手取并列 speaker 中最早出现(最低下标)的词的 speaker;`speaker=None` 的词不投票;无携带 speaker 的词则保持 `None`**。该合成以同一实现跑在两条路径上:batch 在 `EngineBase.transcribe` 的结果后处理(作用于顶层 `segments[]` **与**每个 `channels[i].segments`——TR.4 两视图必须一致),streaming 在标准归约器(`session.result()`)。适配器 MAY 自行预填 `Segment.speaker`(原生段级引擎如此);标准层仅在段级为 `None` 时合成,且不论 diarization 是否被请求(always-on 数据同样受益)。钉死单一规则的理由:同一引擎+同一音频 MUST 经任何路径/实现得到相同的 `Segment.speaker`——两条相近规则(majority vs first)会静默分叉,破坏本特性存在的可移植性。 | ||
| - **标签有效性(构造期强制)**:`speaker` 标签 MUST 非空、非纯空白、且无首尾空白——`Segment` / `Word` / `TranscriptionEvent` 构造期拒绝(`""` 是既非 `None` 又非真实标签的第三种未定义状态;`"A "` 与 `"A"` 是两个不同字串 = 两个不同说话人,一个适配器 off-by-one 即静默打破一致性;**拒绝而非归一化**,与 `phrase_hints` 词条的 fail-loud 立场同款)。`None` 合法。标准**不**规定标签格式(`"speaker_0"`、`"A"`、known-speaker 场景的真实姓名皆可)。 | ||
| - **result 内一致性(适配器义务)**:同一结果内同一字串 = 同一说话人、不同说话人 = 不同字串。一致性范围横跨**所有**标签载体——顶层 `segments[]`、`words[]`、以及 `channels[]` 子结果:逐通道独立 diarize 的引擎(两个通道都把各自第一个说话人标 `"0"`)MUST 由适配器在组装前重标进同一个 result 级命名空间,否则同一字串静默指代两个人。非空性之外的一致性无法构造期强制,合规套件亦**不**校验——套件只提供下方「合规范围」条的负向 presence 交叉检查(`stream_exceeds_diarization` / `result_exceeds_diarization`:只比对「是否携带 speaker」与声明能力,**绝不**比对标签字串一致性);一致性在无多说话人 fixtures 时不可验证,标准层不假装强制。与 TR.2 排序(同为引擎义务、构造期不强制、套件不校验,但渲染器在自身边界防御性重排兜底)不同,此项是**纯适配器义务**——连渲染器都不代为修复,没有任何标准层安全网。 | ||
| - 标签跨会话**不**稳定、**不**关联身份、**不**跨引擎可比。 | ||
| - **always-on 引擎的具名豁免(normative)**:声明 `always_on` 为 supported 的引擎 MAY 在 diarization **未被请求**时填充 `speaker`,这**不是**违规——它是对「未请求的数据 MUST NOT 回填」立场(TR.3 对 word timestamps 的禁令)的**有意、具名**豁免:架构上不可关闭的 joint 模型无法不产出 speaker,强制剥离 = 主动丢弃高价值数据 + 在静默方向(漏剥没人知道)留 bug 窗口。此类引擎 MAY 额外发一条 `info` diagnostic(`code="unrequested_speaker_labels"`)。想要无 speaker 标签的应用(隐私场景)在 always-on 引擎上无标准关闭手段,自行在客户端剥除。可关闭的引擎不享受此豁免(能关 MUST 关,[§能力系统 3.2](#能力系统-capabilities--normative))。 | ||
| - **always-on 引擎的具名豁免(normative)**:声明 `always_on` 为 supported 的引擎 MAY 在 diarization **未被请求**时填充 `speaker`,这**不是**违规——它是对「未请求的数据 MUST NOT 回填」立场(TR.3 对 word timestamps 的禁令)的**有意、具名**豁免:架构上不可关闭的 joint 模型无法不产出 speaker,强制剥离 = 主动丢弃高价值数据 + 在静默方向(漏剥没人知道)留 bug 窗口。此类引擎 MAY 额外发一条 `info` diagnostic(`code="unrequested_speaker_labels"`)。想要无 speaker 标签的应用(隐私场景)在 always-on 引擎上无标准关闭手段,自行在客户端剥除。可关闭的引擎不享受此豁免(能关 MUST 关,[§能力系统 3.2](#capabilities))。 |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift
Disambiguate Word.speaker=None.
Line 685 defines None as “inherit Segment.speaker,” while Line 686 defines None as an explicit unknown speaker. A word with an unknown speaker inside a segment labeled "A" is therefore indistinguishable from a word spoken by "A". Define one unambiguous representation for inheritance versus unknown attribution.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/spec/specification.md` around lines 683 - 691, Clarify the speaker
inheritance model in the specification so Word.speaker=None cannot
simultaneously mean inheritance and explicit unknown attribution. Define a
distinct representation for an explicitly unknown word speaker while preserving
None as the inheritance marker, and update the related None semantics and
segment-speaker synthesis rules to use that representation consistently.
| | `words` | `list[Word] \| None` | 词级细节(可选,与 [§结果模型](#transcription-result) 共享同一 `Word` 定义) | | ||
| | `speaker` | `str \| None` | 段级说话人标签。继承规则与 `Segment.speaker` 相同(TR.5):`event.words[i].speaker` 非 `None` 时在词级覆盖;标签有效性规则同 TR.5(构造期拒绝空/纯空白/带首尾空白)。冻结区域保护见 §4.2 | | ||
| | `start` / `end` | `float \| None` | 段的起止时间(秒,原点 = 会话第一个音频采样)| | ||
| | `audio_processed_until` | `float \| None` | 引擎已处理到的音频时间点(§4.4) | | ||
| | `old_ids` / `new_ids` | `list[str]` | 仅 `supersede` 事件使用(§5) | | ||
| | `detected_language` | `str \| None` | 引擎检测到的语言(BCP-47,非 `auto`;与结果模型同规则校验)。是 §6.3 重连连续性承诺的载体——重连前后 MUST 保持一致 | | ||
| | `code` / `recoverable` / `retriable_after` | | 仅 `error` 事件使用(§7.2) | | ||
| | `reconnect` / `gap_start` / `gap_end` | | 仅 `progress` 的重连通知使用(§7.3) | | ||
| | `extra` | `dict[str, Any]` | 引擎特定/实验数据槽位(默认 `{}`)。语义与 [结果模型](#结果模型-transcription-result--normative) 的 `extra` 一致:**引擎特定、不可移植**,可移植应用代码 MUST NOT 依赖其中的键。提供给适配器透传原生协议的额外信息(如 token 级置信度、自定义元数据),而无需扩展封闭的标准字段集 | | ||
| | `extra` | `dict[str, Any]` | 引擎特定/实验数据槽位(默认 `{}`)。语义与 [结果模型](#transcription-result) 的 `extra` 一致:**引擎特定、不可移植**,可移植应用代码 MUST NOT 依赖其中的键。提供给适配器透传原生协议的额外信息(如 token 级置信度、自定义元数据),而无需扩展封闭的标准字段集 | |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
Do not prescribe logging raw exception details.
The revised error-event contract removes human-readable details from the client payload, but the adjacent rule still permits logging raw str(exc) values that may contain paths, URLs, or credential fragments. This conflicts with IC.3’s requirement that plaintext secrets never be logged. Require redacted, allowlisted structured logging instead.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@docs/spec/specification.md` around lines 950 - 958, The error-event contract
must not permit logging raw exception text. Update the adjacent error-logging
rule to require redacted, allowlisted structured fields only, excluding paths,
URLs, credentials, and other untrusted exception details, while preserving the
client payload’s removal of human-readable error details.
- installation/quickstart: install from PyPI (live since v0.1.1), git install demoted to a from-source section - surface diarization in every app-developer path (params example, result loop, streaming event table, README supports() block) - CHANGELOG: fill [Unreleased] with #31/#32 and the roadmap move - mkdocs nav: API-reference labels updated to the post-restructure module paths; enable attr_list - spec: stable explicit heading ids replace 42 broken CJK-slug anchor links; design-note references point at the renamed docs/design-notes/ - errors.md: correct StructuredError field names (.param/.hint/.details); add UnsafeAudioUrlError to the hierarchy tree - plugin_entrypoints: transcript captured live against std-faster-whisper -- list, show (incl. the config-schema section), compliance entrypoints, and compliance run with the two-check disclosure -- abridged with elision markers and labeled as such. Captured with the fix/toolchain-honesty CLI, so that branch must merge first. Stale future-tense checker claim rewritten. - errors.md: InvalidSessionUseError example corrected (end_audio is idempotent; double-feed is the real programming error) - streaming.md: progress/error rows no longer claim segment_id is always None (spec 4.1 allows either to carry the segment id)
…reaming cadence Both rebuild documents lost before ever being committed, then settle them: - release-pipeline-redesign: v0.1.0 burn post-mortem, the two root causes (never-rehearsed release path; validation after the irreversible act), and the decided single-dispatch pipeline — guards -> TestPyPI (inline rehearsal) -> PyPI -> GitHub release last -> automated dev-bump PR. - streaming-cadence-and-tuning: output_latency capability node, target_latency_ms runtime param, preferred_stream_chunk_ms hint; decisions D1-D7 with engine facts verified against official upstream sources. Spec 10's defer list now points at the settled streaming-cadence case (the spec records that a decided design exists instead of deferring silently; the full normative text lands with the implementation). The Voxtral row links its verified sources (HF card + paper) and 3 notes how to re-verify the rest; the RELEASING.md no-op-gate claim is scoped to what the runbook actually says (an optional, currently-unprotected gate); a superseded roadmap-draft reference in D2 is labeled as such.
3b4fc54 to
7319880
Compare
Bundles the docs work from the 2026-07-05 planning session (3 commits, squash-ready).
1. Roadmap consolidation
Delete
docs/roadmap.md— issue #27 declared itself the canonical roadmap and the committed page had drifted (still listed the first PyPI release as pending, counted 6 compliance dimensions). Docs nav links the issue directly, same pattern as the external Releasing entry.2. Staleness refresh (10 files)
discover_and_use.md), streaming event table gains thespeakercolumn, READMEsupports()block. All examples verified against the real API (DIARIZE,RuntimeParams.diarization,Segment.speaker).[Unreleased]filled with feat: add speaker diarization to the standard #31 / refactor: group modules into subpackages; de-jargon comments #32 / the roadmap move.{#id}anchors (attr_list), fixing all 42 broken internal cross-references; §10's defer list now points at the settled streaming-cadence design case; stale设计笔记和决策/paths now point atdocs/design-notes/.StructuredErrorfield names corrected to.param/.hint/.details;UnsafeAudioUrlErroradded to the hierarchy tree.list,show(incl. the new config-schema section),compliance entrypoints,compliance runwith the two-check disclosure — abridged with...markers and labeled as such; stale future-tense compliance claim rewritten. ⚠ Captured with thefix/toolchain-honestyCLI: merge fix: make the toolchain honor its own promises #41 before this PR.3. Settled design cases (docs/feat_plan/)
output_latencycapability node,target_latency_msparam,preferred_stream_chunk_mshint; decisions D1–D7, engine facts verified against official upstream sources (incl. a survey correction: Voxtral's delay dial is 80 ms-stepped, not continuous; the Voxtral row links its HF card + paper). Settles open question 4 of issue Runtime compliance: end-to-end inference verification & robustness probes #33 (the issue itself stays open — it tracks the runtime e2e compliance implementation); Roadmap #27's design-case links become valid on merge.Verified:
mkdocs buildexit 0 with zero link/anchor messages (the 297 pre-existing griffe docstring warnings are fixed separately onfix/griffe-docstring-format).Summary by CodeRabbit
Summary by CodeRabbit
New Features
Documentation