docs(pages): correct FAQ JSON output shape and plan-threshold cost lever - #1190
Conversation
The FAQ told integrators that a review with zero findings emits a bare empty array. `review --format json` always writes exactly one JSON object; `[]` is the value of its `comments` field. The two states the entry claimed were distinguishable by shape are in fact the same shape and differ only in `summary.files_reviewed` and `manifest.terminal_state`. The leaner no-`summary` object the entry described is what `ocr scan` emits, because `outputJSONNoFiles` is reachable only when the run manifest is nil, which the review path never produces. The cost lever was inverted as well: `PlanRequired` triggers when the changed-line count reaches a threshold, so raising the thresholds is what skips planning and saves the call. The two thresholds are also not symmetric at zero -- `PLAN_MODE_LINE_THRESHOLD <= 0` means always plan, while `PLAN_MODE_GROUP_LINE_THRESHOLD == 0` disables the group gate -- so the blanket sentence is split rather than merely reversed. Applied to all five maintained locales. Headings are left verbatim so heading ids and existing fragment links keep working; the plan-phase entry is cross-referenced by name instead of by anchor to avoid non-ASCII slug differences between locales. No code change: `outputJSONNoFiles`, `outputJSONWithWarnings`, `manifestMessage`, and `PlanRequired` are all correct and already covered by tests. Closes alibaba#1189
|
✅ OpenCodeReview: Review skipped: no items were selected. |
|
还在检查和修改 |
Avoid implying that skipped and zero-finding review JSON have identical serialized key sets: both are JSON objects with comments: [], but optional top-level fields may differ. Also qualify the group-threshold-zero cost note: disabling that gate saves a plan call only when it would otherwise be the sole trigger.
Avoid presenting a partial `ocr scan` no-files object as the complete JSON output. Document the missing `summary`, always-present `tool_calls`, and optional identity/trace metadata across all maintained locales.
|
Nice piece of work — I checked every claim against the source and they all hold up: 1. -- [Телеметрия](../telemetry/) — использование токенов и метрики LLM.
+- [Телеметрия](../telemetry/) — использование токенов и метрики LLM.
\ No newline at end of fileUnrelated to the correction, and nothing in CI will catch it. Worth restoring so the diff really is limited to the two entries. 2. The lean no-files path isn't 3. For what it's worth, I also checked the heading-anchor argument and I think you're right to leave the headings alone — |
|
Thanks for the careful pass — all three points make sense. I'll restore the RU EOF newline, reframe the lean output as the manifest-less path rather than scan-specific, and make tool_calls unconditional in the other four locales. I'll also tighten the heading-anchor note in the PR description. |
Describe the lean no-files JSON as a manifest-less path rather than scan-specific, make `tool_calls` presence explicit across locales, and restore the Russian FAQ trailing newline.
|
Thanks for the careful pass — addressed all three points in
I also kept the existing headings unchanged, per the fragment-compatibility constraint you pointed out. |
Description
Summary
en,zh,ja,ko,ru).review --format jsonas returning a bare[]for a successful zero-finding review, putfiles_reviewedat the wrong level, and suggested distinguishing "nothing to review" from "reviewed with no findings" by JSON shape.summaryandmanifestbeing absent, and documentstool_callsas unconditional whilellm/trace_idremain optional.Drafted against
main@e967f3f4cf40e2f1e1154117763382b24bd608e4.Full investigation, code citations, measured output, and the original problem report are in #1189.
Why the old text was wrong
1.
review --format jsonnever emits a bare arrayThe old FAQ said that a normal review with zero comments produces a regular empty array:
That output shape is not produced by the normal review JSON path.
outputJSONWithWarningsserializes ajsonOutputstruct.commentsis a field of that object, not the JSON document itself.The existing tests already pin this behavior:
TestEmitRunResult_JSONHasNoReportTextdecodes stdout as JSON and verifies that exactly one JSON document is present.TestOutputJSON_NoCommentsunmarshals zero-comment output intojsonOutput, which would fail if stdout were a bare array.So
review --format jsonwrites one JSON object to stdout, withcomments: []when there are no findings.2.
files_reviewedis not a top-level fieldThe old FAQ heading suggests:
{ "files_reviewed": 0, "comments": [] }On manifest-backed review output,
files_reviewedlives undersummary:For a manifest-backed review where nothing is eligible, measured output contains:
status: "skipped"summary.files_reviewed: 0comments: []message: "Review skipped: no items were selected."manifest.terminal_state: "skipped"The manifest-less no-files path described below omits both
summaryandmanifest, so callers must tolerate both fields being absent.The heading is intentionally left unchanged for compatibility; see "Compatibility constraints" below.
3. "Nothing to review" and "reviewed with no findings" are semantic states, not array-vs-object shapes
A manifest-backed review that actually examines files and produces zero findings also returns a JSON object with:
but its semantic values differ from a manifest-backed review where nothing was eligible:
summary.files_reviewedreflects the files actually reviewedstatusis"complete"manifest.terminal_stateis"complete"messageis"Review complete: 0 finding(s) across N selected item(s)."The first draft of this correction described these two cases as having "the same object shape". That was still too strong.
jsonOutputhas optional top-level fields such as:groupswarningsproject_summaryresumeretry_reporttrace_idand their presence can differ between runs.
In particular, a no-files review exits before grouping, while a review that actually dispatches files can populate
groups.The stable contract is therefore:
review --format jsonwrites one JSON object, never a bare array;comments: [];summary.files_reviewed,status, ormanifest.terminal_state;summaryandmanifestbeing absent on the manifest-less no-files path; and4. The leaner output is the manifest-less no-files path
outputJSONNoFilesis reached when the output pipeline has no run manifest and the no-files guard matches.ocr scanis always manifest-less because the scan agent deliberately returnsnilfromRunManifest().ocr reviewnormally produces a run manifest, but it can also reach this path when manifest construction fails and the no-files guard matches.Measured on the manifest-less no-files path:
statusis"skipped"messageis"No supported files changed."commentsis[]summaryandmanifestare absenttool_callsis always presentllmortrace_idmay be presentThe corrected FAQ describes these field semantics without presenting a selected field subset as the exact complete JSON shape.
5. The plan-threshold cost lever was reversed
The old FAQ said:
Template.PlanRequireddoes the opposite for positive thresholds: planning is enabled when the changed-line count reaches a threshold.Conceptually:
Therefore:
This also fixes a contradiction with the existing "Plan phase took forever and the file is small" FAQ entry, which already describes planning as switching on when a threshold is reached.
6. The two plan thresholds are asymmetric at zero
This could not be fixed by merely swapping "lowering" and "raising".
PLAN_MODE_LINE_THRESHOLD <= 0hits the early return and means:That is the most expensive setting for this gate.
By contrast:
fails the group's
> 0guard and disables the group-total trigger.That can save a plan call when the group-total gate would otherwise have been the only trigger.
It does not necessarily save a call when the per-file threshold is already satisfied.
Both zero cases are covered by named tests:
"per-file threshold zero means always plan""group threshold zero disables group gate"What Changed
English: JSON output entry
The corrected entry now distinguishes manifest-backed review output from the manifest-less no-files path:
The same contract is stated across all five maintained locales.
English: plan-cost entry
The corrected cost guidance says:
The same corrections are applied in translation to
zh,ja,ko, andru.Each locale keeps its existing style rather than being mechanically back-translated from English.
Compatibility Constraints
Headings are intentionally unchanged
The affected FAQ headings remain byte-for-byte unchanged in all five locales.
The Korean entry has an explicit anchor:
The other locales derive their heading IDs from the heading text through the Pages heading-ID machinery.
Renaming those headings would silently change existing fragment URLs and could break inbound links. The heading therefore still names the historical/mistaken JSON shape even though the body immediately explains the real structure.
This cannot be repaired later by simply adding an equivalent legacy
{#...}alias: the explicit heading-ID parser accepts only ASCII identifiers, while generated fragments for the existing Chinese and Japanese headings preserve CJK characters. A safe rename needs broader heading-ID support or a fragment-redirect mechanism before the localized headings can change.The plan-phase cross-reference remains textual
The cost entry refers to the earlier "Plan phase took forever and the file is small" entry by name instead of adding a relative
#...link.The localized headings generate different non-ASCII fragments. Pages also has special handling because
markedpercent-encodes non-ASCII hrefs while generated heading IDs remain raw andDocsPage.tsxdecodes the fragment before lookup.Keeping the cross-reference textual avoids introducing five additional locale-specific anchor cases into this documentation fix.
Type of Change
How Has This Been Tested?
Validation Environment
Initial full local validation was performed against:
v24.14.011.9.0go1.26.5 windows/amd64e967f3f4cf40e2f1e1154117763382b24bd608e4(origin/main)pages/node_modulesdependency tree, unchangedSubsequent commits only tightened wording in the same five Markdown files after additional review found over-broad descriptions of the JSON contract. They introduce no executable, configuration, or dependency changes.
Pages validation
The following Pages gates were run locally on the initial documentation change:
npm run lint— exit 0react-hooks/exhaustive-depswarnings inHeroSection.tsxandMarkdownRenderer.tsxnpm test— 8 files, 38 tests, all passingnpm run typecheck— exit 0production webpack build — exit 0
npm run size— 95.13 kB brotli against the 150 kB limitThe production build was run as:
under Git Bash.
The repository's
npm run buildcommand itself is POSIX-oriented and does not run directly in the same Windows environment. That separate build-script portability issue is documented in #1181 and is intentionally not addressed here.Go behavior validation
The packages whose behavior is described by this documentation were tested:
go test ./cmd/opencodereview/... ./internal/config/template/...Both passed.
These cover the two relevant implementation areas:
Template.PlanRequiredNo Go file is modified by this PR.
Render verification
The FAQ is rendered through the Pages Markdown pipeline:
rather than being compiled as MDX.
The rewritten sections were rendered through the project parser to verify that:
<code>;Behavioral evidence
The documentation was checked against runtime output rather than relying only on source inspection.
Manifest-backed
ocr reviewwith nothing eligibleA freshly built binary was run in a repository whose only staged change was a Markdown file, which OCR excludes.
ocr review --format json --audience agentproduced:0summary.files_reviewed: 0comments: []status: "skipped"message: "Review skipped: no items were selected."manifest.terminal_state: "skipped"Manifest-less no-files output
ocr scan --format json --audience agentin the same repository produced the manifest-less no-files path:status: "skipped"message: "No supported files changed."comments: []tool_callspresentsummarymanifestocr scanis always manifest-less.ocr reviewcan also reach this path when manifest construction fails and the no-files guard matches.tool_callsremains unconditional; only metadata such asllmortrace_idis optional.Review with files examined and zero findings
The manifest-backed review path reports:
rather than the legacy
"success"plus"No comments generated. Looks good to me."pairing.outputJSONWithWarningsinitially constructsStatus: "success"but replaces it withmanifest.TerminalStatewhen a manifest is present.The review agent normally has a manifest; the
"success"pairing survives only on manifest-less legacy paths.Threshold evidence
The cost guidance was checked against both
Template.PlanRequiredand its existing tests.The important cases are:
and:
The second case can avoid the plan call only when the group-total gate would otherwise have been the sole trigger.
OCR Coverage
The required OCR self-review was run as instructed by
AGENTS.md.It selected no files:
ocr review --previewexplained why: all five changed FAQ files were classified asunsupported_ext.The zero-comment OCR result is therefore not treated as evidence that this PR is correct.
The substitute verification is the runtime measurement and existing implementation tests described above.
Incidentally, the skipped self-review printed:
which is the exact message documented by the corrected FAQ.
Final Validation Notes
make checkwas deliberately not run locally.It includes repository-wide mutating steps such as
go mod tidyand formatting operations over Go files that this documentation-only PR does not touch. Targeted Go tests and the Pages validation were used instead.license-checkis not applicable to the changed Markdown files.english-checkdoes not scan.md, which is what permits the localized FAQ files to contain their respective languages.Screenshots
FAQ JSON output
Before:
After:
Plan-threshold cost guidance
Before:
After:
Desktop viewport. The five maintained locales use the same documentation
layout; this PR changes localized prose only, with no component, styling,
navigation, or responsive-layout changes.
Interaction With Other Open PRs
Several other open PRs currently touch the same FAQ files but not the lines changed here:
--max-toolsdocumentation.These may cause line-number drift when rebasing, but no textual overlap with the sections changed here is currently expected.
Checklist
The current PR's CLA check is authoritative.
For historical context, the same contributor account also passed
license/claon the previously merged #1091.Known Limitations
summaryandmanifestare absent.outputJSONNoFiles,outputJSONWithWarnings,manifestMessage, andPlanRequiredalready implement the intended behavior; only the prose describing them was wrong.Related Issues
Closes #1189.