Uh oh!
There was an error while loading. Please reload this page.
Developer guide: a chapter that was never in the book, and the gates that would have said so - #5664
Conversation
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:228e86c35d
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Developer Guide build artifacts are available for download from this workflow run:
Developer Guide quality checks: |
Cloudflare Preview
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:ba55f8daf1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:53c9399c30
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:f7ad626621
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:15fc060d09
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:49266353f1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:67c22f7adb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:6e836c0eda
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:cb268cf5aa
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:04a33dbbe1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:0b35e2e37a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:10ad8fc3c9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:73816278a9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:845b6296af
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:39aa63aecb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:090c99fc6a
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:ab014e9e3c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:d6d293803b
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:12ae87fa38
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
✅ Continuous Quality ReportTest & Coverage
Static Analysis
Generated automatically by the PR CI workflow. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit:6108cadc07
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Uh oh!
There was an error while loading. Please reload this page.
… said so The developer guide shipped four structural defects that every existing gate passed. All four are reproducible by rendering the book and reading the result back, which is what the new checks do. "Working with the native Linux port" was not in the manual. Its include sat on the line directly after Working-With-Windows.asciidoc, whose last line is a paragraph, so after include expansion the Linux chapter's title became a continuation of that paragraph and the whole chapter rendered as sections 94.9-94.13 of the Windows one. Asciidoctor reports nothing for this. Accessibility-Semantics, MCP-Headless-API and Media-And-Audio opened with a level-0 heading. Under doctype:book that makes each a *part*, promotes its own sections to chapters and deletes its title from the sequence -- 22 of the book's "chapters" were really sections of those three. Six documents were included by nothing. component-selector.asciidoc (the live ComponentSelector API), SVG-Transcoder.asciidoc and Video-Capture-Constraints are now in the book; Casual-Game-Programming is superseded by the card-game case study in Game Development and is deleted with its two images; cn1libs.asciidoc was a stub; Home.asciidoc's live links move into the preface. Eight cross-references pointed at ids that do not exist. Asciidoctor renders <<missing,Some words>> as an ordinary link to nowhere, so these looked fine. The Application Lifecycle sidebar the introduction cites twice was written all along -- it just had no anchor. Sixteen links to codenameone.com/manual/<chapter>.html: the site serves /manual and /manual/ exactly, with no splat. Each sat in an HTML/PDF fork whose commented-out PDF branch was already the internal xref that works in both backends, so the fork is collapsed onto it. The ~90 chapters are now grouped into parts. Index.asciidoc, which is the introduction and not an index, is renamed accordingly. New gates, all four verified to fail when the defect they describe is reintroduced: check-guide-structure.py every document is in the book or declared out of it; no chapter silently becomes a part; every included title survives into the rendered output check-guide-xrefs.py every internal link resolves, and none renders as a bare "[some-id]" check-missing-code-blocks.py prose that promises a listing and is followed by a hole -- 409 of them, from the snippet extraction in bbdc605, recoverable from bbdc605~1 check-guide-links.py links checked against the paths the site actually serves, derived from _redirects and the content tree rather than a hand-written list The last two carry shrinking baselines, in the shape of cast-semantics-baseline. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review found the link checker was reading Hugo's routes wrong, and it was right: 1055 of the 1262 content pages override their published route with a `slug`, so deriving the path from the filename both invented routes that are never generated and rejected real ones. `content/demo-poker-demo.md` declares `slug: "poker-demo"`, and the checker accepted `/demo-poker-demo.html` while rejecting `/poker-demo/`. Front matter is now parsed for `url`, `slug` and `aliases`, which is what actually decides the route. The same pass removes the prefix allow-list. `/blog/` on it meant any `/blog/anything` link passed unchecked, even though the 922 blog pages are right there in the content tree; static assets are now enumerated from `docs/website/static/` rather than waved through by prefix. Only `/javadoc/` and `/developer-guide/` remain exempt, because both are produced by a build and cannot be enumerated from this repository. Deploy-time redirects are read out of the script that emits them, so `/files/developer-guide.pdf` -- written into `_redirects` at deploy time, not committed -- resolves. Known paths go from 2625 to 4353, and the baseline gains one entry: a genuinely dead `/files/iOS_UI-Kit.psd` that nothing serves. The review also asked for `docs/website/**` in this workflow's trigger paths, so that a route change here re-runs the link check. The gap is real but the fix would run the entire guide build -- maven install, demo build, screenshot generation -- for every blog post the daily publisher pushes, to execute one Python script. The check instead runs from website-docs.yml, which already triggers on `docs/website/**` and needs nothing but a checkout. Both workflows carry a comment saying so, because the reasoning belongs where the next reader looks rather than in a review thread. Also: the two snippet files touched here get the Codename One header the copyright gate requires of modified source, and check-guide-xrefs.py drops a computed-but-unread local. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Removes "How to contribute updates" from the preface. Nothing in it is lost: where the guide is published and what it covers are both already stated under "Where else to look". The same fact makes four other passages wrong, so they go with it rather than leaving the guide asking for patches on one page and not the next: - The preface described the docs as "reviewed through pull requests", which read as the way in for a reader. - The author list asked readers to add their own name. - The repository bullet advertised pull requests alongside source and issues. - "Add your template to Codename One intializr" solicited third-party project templates through the issue tracker. - "A path to contribute improvements back to the Codename One core" was one of three reasons the sources chapter gave for building the SDK. The other two stand on their own. - The SQLMap limitation note in io.asciidoc asked for pull requests on the parts it does not map. The "Debugging Codename One sources" section in performance.asciidoc was a fork-and-pull-request walkthrough and also pre-Maven -- it drives the NetBeans "Team > Git > Clone" menu and the Ant "build & run libraries" section, neither of which exists in a Maven project. It is replaced by a pointer to the sources chapter, which documents the current flow. Left alone: three "file an issue" mentions in Working with iOS, ComponentSelector and CSS. Those report a rendering regression, a missing wrapper method and a missing PPI table entry -- bug and feature reports, not code contributions. Dropping the walkthrough took two plain-http github.com links with it, so the link baseline shrinks from 39 to 37. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two review findings, both real. A baselined entry that no longer reproduces was only a printed reminder, so it stayed in the file and kept a slot open: a later change could restore that exact file and URL, `current - baseline` would still be empty, and the regression would pass. A ratchet that never banks its fixes is not a ratchet. Both checkers now fail on a stale entry and name the command that banks it. Verified by filling one of Commerce's holes and by repointing the dead PSD link -- each fails until the baseline is rewritten. `docs/website/static/_redirects` carries 21 wildcard rules, and recording `/files/cn1libs/*` as a literal string meant a real link to `/files/cn1libs/SomeLib.cn1lib` matched nothing and would have been reported broken. Splat and `:placeholder` sources now compile to patterns. No guide link hits one today, so this was latent rather than failing, but both workflows would have rejected the first one written. Verified in both directions: a link under a wildcard is accepted, and `/files/not-a-real-prefix/Thing.zip` is still rejected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two more review findings on the link checker, both real. Redirect destinations were being recorded as served routes. A rule whose target was deleted still parses fine, so `/old -> /gone` was making a guide link to `/gone` pass. Only the source counts now. Of the 923 destinations that were not also sources, exactly one route depended on being trusted -- `/` -- and Hugo renders the home page whether or not `content/_index.md` exists, so that is added explicitly rather than inferred from a redirect. Unpublished pages were also being treated as routes. Hugo defaults buildDrafts and buildFuture to false, so a `draft: true` or future-dated page is not served and a link to it is broken. Both are now excluded. The date test does make the result depend on the day it runs, which is noted in the code because it is a real drawback -- it is kept because it mirrors what the site actually serves. Neither case exists in the tree today (0 drafts, 0 future-dated), so this closes a latent false pass rather than fixing a live one. Verified in both directions: a link to a redirect destination that nothing serves is now rejected, and a link to a draft page is rejected until the front matter says `draft: false`, at which point it passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two more review findings, both producing real false results.
`docs/website/static` was walked with `rglob("*")` and every entry recorded,
directories included. Copying `static/uploads` to the site does not create a page
at `/uploads`, and seven of the top-level static directories have no index page
at all, so a link to any of them passed. Only files are recorded now, plus the
parent of an `index.html`, which is what actually produces a directory route.
`http://localhost:11434/v1` -- the Ollama endpoint the AI chapter documents --
was being reported as insecure. `LOCAL_HOSTS` was consulted for the has-no-dot
check but not for the TLS check, so every localhost, 127.0.0.1 and 0.0.0.0
example failed. A local development service is not expected to terminate TLS.
The stale-entry rule added in the previous commit caught this on its own: as
soon as the exemption landed, both localhost entries were reported as fixed but
still baselined. The baseline shrinks from 37 to 35.
Verified in both directions: a link to `/uploads/` is now rejected, and
`/files/javadocs.zip`, a real file under static, still passes.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>… match `_redirects` ends with `/*.html /:splat/ 301`, which matches every root-level .html path there is. Treating a wildcard match as proof the link works meant `/this-page-does-not-exist.html` passed -- the same mistake as whitelisting a prefix, arriving through a different door. The captures are now substituted into the destination and that is checked instead, recursively, with a depth limit so a loop in the table cannot hang the run. A rule pointing off-site is still accepted because nothing here can verify it. The real .html links keep working: /developer-guide.html, /blog.html, /how-do-i.html and /discussion-forum.html all resolve, and /files/cn1libs/a.cn1lib resolves through its wildcard to an external host, while /this-page-does-not-exist.html and /nonsense do not. Also documented a gap this exposed: Hugo generates taxonomy term pages from front-matter tags rather than from files, so /tags/<term>/ is not derived. No guide link targets one, and if one is added it will be reported as broken -- the safe direction for a gate to be wrong in. The second finding is that `--write-baseline` can bury a new failure as easily as it banks a fix. That is true of the repository's existing ratchets too -- check-cast-semantics.sh rewrites its baseline unconditionally -- and the real control is that the baseline diff is read in review. Still, the accidental case is worth closing: both checkers now refuse to ADD entries unless `--allow-new` is passed, so shrinking stays frictionless and recording new debt is a deliberate act visible in the command as well as the diff. Verified that a new broken link cannot be baselined away without the flag, that it can with it, and that banking a genuine fix needs no flag at all. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The previous commit stopped trusting a wildcard match and followed it to its destination. Review pointed out the literal rules deserve the same treatment, which is right: a literal source is a rule, not a route, and a rule pointing at a page that was later deleted sends the reader to a 404. Every rule is now followed, so `known` holds only paths something actually produces. Measured before changing anything: no guide link resolves solely because its literal redirect source exists while the destination is gone, so this closes a latent hole rather than fixing a live break. The count of bad links is unchanged at 35. Probing the change in the direction it was meant to still work caught a bug in it: following a redirect into `/developer-guide/` failed, because the exemption for build-produced trees lived at the call site and `resolves()` never saw it. A generated tree is reachable both directly and through a redirect, so the test belongs inside `resolves()`. The call site no longer duplicates it. Verified in both directions: `/manual/` and a `/javadoc/...` URL resolve through their redirects, and a rule pointing at a destination nothing serves is still rejected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The structure gate rejected a level-0 heading, because that turns a chapter into a book part. Review pointed out the mirror case was still open: a file the manifest includes directly that opens at level 3, or carries no heading at all, renders as a section of whatever chapter precedes it. That is the same silent nesting defect the gate exists for, arriving from the other side. The rendered-title check could not catch it either. It accepts a title at any depth, so a chapter demoted to a subsection still has its title present in the output, and a headingless file is skipped entirely. The rule applies only to entries the manifest includes DIRECTLY. Nested fragments legitimately start deeper -- the twenty appendix_goal_* files open at level 3 under their parent -- and an include carrying leveloffset is shifted on purpose. All 90 direct entries already satisfy this. Verified three ways: a direct include demoted to level 3 fails, one stripped of every heading fails with the headingless message, and the level-3 appendix fragments still pass. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The chapter-level rule added last commit skipped any direct include carrying a leveloffset, which left the same nesting bug one step along: '== Chapter' at leveloffset=+1 renders as a subsection, and the outcome check cannot see it because it accepts a title at any depth. A leveloffset shifts every heading in the included file, so what decides whether an entry renders as a chapter is the declared level plus the offset. That sum is now what the rule checks, and a headingless direct include fails whatever its offset. No direct entry carries an offset today, so this is closing the bypass rather than fixing a live break. Verified both ways: '==' at leveloffset=+1 fails because it lands at level 3, and '=' at leveloffset=+1 passes because it lands at level 2. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…wice Both baselines were keyed by (file, finding) in a set, so repeats of the same finding in one file collapsed into a single entry. Two identical introducing sentences, or the same broken URL named twice, are two things to fix, and the second was free: it could appear later without the check noticing. Not hypothetical on the link side. The checker found 38 occurrences while the baseline recorded 35, so three Freshdesk URLs in Advanced topics were already being hidden by their own duplicates. They are now recorded, which is why the baseline grows by three -- banked with --allow-new, which is exactly the deliberate act that flag exists for. Both baselines are now multisets: one line per occurrence, compared with Counter arithmetic, so an entry appearing twice needs two lines. The missing-code-block report also names every line a repeated sentence sits on rather than the first. Verified by adding a second occurrence of an already-baselined URL to the SAME file -- the file boundary was doing the work in an earlier probe, which is why that probe proved nothing -- and by duplicating one of Commerce's promising sentences, which is now reported at both line numbers. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The fence list treated ==== example, **** sidebar and ____ quote blocks the same as listings, so every promising sentence inside one was skipped. Those delimiters hold ordinary AsciiDoc, and six real holes were hiding behind them in basics.asciidoc -- including the setSameWidth/setSameHeight example this PR's own description cites as the canonical case. It sits in a sidebar, so the check written to find it could not see it. That also explains a number that had been quietly wrong: the first measurement of this defect, before the fence handling existed, found 415. Adding container delimiters to the fence list dropped it to 409, and the drop looked like the fence handling working rather than a blind spot opening. The count is 415 again, and the baseline grows by six, banked with --allow-new. The structure checker carried the same fence list. Narrowing it there changes nothing today -- the twelve includes that sit inside container blocks are all snippet includes, which that walk skips anyway -- but a chapter include or a heading inside a sidebar would have been invisible to it, so both scripts now agree on what a fence is. Verified both directions: a hole inside a sidebar is now reported, and prose inside a listing block is still ignored. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…erable Two review findings. The missing-block detector treated "sentence, two blank lines" as proof the listing was gone, without looking past the blank run. An introduction separated from its block by an extra blank line is untidy, not a hole, and nine of the baselined entries were exactly that -- the block is right there. Reporting them would also have made the gate reject valid AsciiDoc spacing for anyone adding one. The detector now skips the blank run and checks whether a block actually starts, conservatively: only unambiguous starts count, so a real hole is never explained away. The count drops from 415 to 406, and the stale-entry rule identified all nine on its own. That is the second correction to this number today, both in the same direction as the evidence rather than my confidence: 415 measured, 409 after a blind spot was introduced, 415 when it was removed, 406 now that false positives are gone. The second finding: `/developer-guide/` was still blanket-exempt while `/blog/` had been made route-specific, so `/developer-guide/does-not-exist` passed. `scripts/website/build.sh` rsyncs this directory to the site excluding `sketch/` and the AsciiDoc sources, which makes every served path under the guide enumerable. It is derived now, and only `/javadoc/` remains exempt -- genuinely unenumerable, since it is produced from the framework sources at build time. Verified: the guide root and a real image under it resolve, while a fabricated path, a Sketch source and an AsciiDoc file do not. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`_visit` returns early on a revisit, so a second include of the same file left no trace in the reachability map, and the title check could not see it either -- it asks whether a title appears AT LEAST as often as declared, which two renderings of one chapter satisfy. Including a chapter twice therefore duplicated it in the manual while the structure gate reported success. Confirmed before fixing: with Printing included twice, the gate passed and the rendered book contained the chapter twice. Includes are now counted at the edge rather than inferred from visited state, and any document included more than once is rejected. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The rule added last commit counted every textual include, which would have rejected two legitimate shapes: a nested fragment reused from more than one parent, and a chapter included once per branch of an ifdef/ifndef pair, which appears twice in the source and once in the output. Neither is a duplicated chapter, and this guide already uses the conditional pattern elsewhere for the PDF backend. Counting is now limited to direct manifest entries that are not inside a conditional region. The defect the rule was written for -- a chapter listed twice in developer-guide.asciidoc and rendered twice in the book -- is still rejected. Verified all three: the duplicate manifest entry fails, a nested fragment included from two parents passes, and the same chapter under mutually exclusive ifdef/ifndef branches passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two review findings, both on fixes from the previous two commits. The missing-block detector classified any line beginning with *, -, + or . as markup, so an introduction written as a bulleted list item was skipped. Stripping a valid list marker -- one followed by whitespace, which distinguishes '* Item' from '*bold*' and '. Item' from '.BlockTitle' -- lets the prose test see the sentence. Worth being precise about the effect: numbered items were already scanned, because digits were never in that prefix list, so this closes the bulleted case and finds nothing new in the guide today. The count stays at 406. The conditional guard added last commit skipped too much. It excluded a conditional manifest entry from `direct` entirely, so the chapter-level and spacing checks stopped applying to it and a conditionally included file opening at level 3 would have rendered as a subsection unnoticed. Only the duplicate count skips a conditional now; everything else treats it as the chapter it is. That required one more correction in turn: an include closed by endif:: on the next line is correctly spaced, because a preprocessor directive is not content and cannot absorb a paragraph. Verified: a bulleted introduction with a missing block is reported, a block title is still markup, a conditional chapter at level 3 is rejected, and the same chapter under two exclusive branches still passes. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ional Two review findings, both latent: nothing in the tree exercises either path today. Closing them anyway, since both are cheap and both are the kind of gap that only shows up once someone writes the markup. The front-matter reader understood a YAML block sequence under `aliases:` and an inline array, but not a multiline array. Three pages use TOML front matter and none of them declares aliases, so nothing changes today; the reader now accepts either continuation shape and closes the array on its bracket. The title-survival check required every direct entry's title to appear in the render, which is wrong for a chapter inside an ifdef/ifndef branch: only one branch renders, so demanding both reports a chapter that is deliberately absent. Conditional entries are excluded from that check and still have their heading level and spacing validated -- the checks that can be evaluated without knowing which branch is active. Verified: a multiline TOML alias array is parsed and both aliases resolve, and the same chapter under two exclusive branches no longer trips the title check. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The structural repairs here -- the chapter that was missing from the book, the three that rendered as parts, the six documents included by nothing, the dead cross-references and the contribution material -- have been stable through nineteen rounds of review without drawing a single finding. The four guard scripts written alongside them drew twenty-six, and are eight times the size of the change they were meant to protect. They are genuinely better for that scrutiny, and one of them found a bug in the instrument this PR used to measure its own headline number. But they are tooling, they iterate on a different clock from the prose, and keeping them here means the documentation fixes wait on them. They move to a PR stacked on this one. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Review is right that including this chapter published an incomplete one: four of its five examples were holes, so a reader could not create a constraint, pass it to Capture.captureVideo, query support, or test whether an explicit size was honored. The originals are recoverable, so they are restored rather than the include deferred -- the chapter documents a real API and was invisible before. One of them never compiled. The original wrote `new VideoCaptureConstraint()`, a class that does not exist; it is `VideoCaptureConstraints`. Corrected while restoring, along with the multiplication signs in the comments, which no .java file in this repository may contain. The support table was also wrong, and this is the finding worth having: it told JavaScript/iOS readers that size, quality and maximum length are all supported. `HTML5Implementation.captureVideo(VideoCaptureConstraints, ...)` takes the unconstrained path whenever `isIOS()` is true and says so in a comment, so an application following that table silently gets video ignoring every constraint. The prose directly above the table already said "not on iOS" and contradicted it. The row now reads No across the board. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…nsupported This chapter is newly published by this stack, so its support table starts advertising that JavaScript Desktop and Android honour the quality constraint. Review checked that against the runtime and found the API disagreeing. The compiler expresses quality as a resolution -- QUALITY_LOW becomes 640x480, QUALITY_HIGH becomes 1280x720 -- and then called `out.preferredQuality(0)`. Since build() copies the resolved quality straight off that object, every caller that asked for a quality got isQualitySupported() -> preferredQuality == 0 || quality == preferredQuality -> false because the preferred value was nonzero and the resolved value was zero. The capture had in fact been constrained exactly as requested. Note the table is right about the platform and the predicate was wrong about it, so the fix belongs here rather than in the table: marking the row unsupported would have made the guide describe the bug instead of the behaviour. The resolved quality is now reported back, but only when the device actually produced the size that quality maps to. getUserMedia negotiates rather than guarantees, so a camera that cannot reach 1280x720 returns something smaller, and in that case the quality genuinely was not honoured and still reports false. A caller that pins width and height itself never enters the branch, so an explicit size plus a quality still reports the quality unsupported, which is correct -- the size wins. Verified the module really compiles this source rather than unpacking it from a jar: a deliberate syntax error fails the parparvm build, and the restored file builds clean. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
6108cad to
e113f04CompareFollow-on from the quality fix: preserving the negotiated quality in the JavaScript compiler still did not reach a caller who asked the obvious question first, because isQualitySupported() never triggered the resolve. Every getter of a resolved value calls build() -- getWidth, getHeight, getQuality, getMaxFileSize, getMaxLength -- and so do isSizeSupported() and isMaxLengthSupported(). isQualitySupported() and isMaxFileSizeSupported() did not. Calling one of those two FIRST on a fresh constraint therefore compared the caller's preference against a field the platform had never filled in, and answered "unsupported" for a constraint the platform honours. isSupported() hid the defect completely, because it evaluates isSizeSupported() first and that builds. So did any code that read a getter before probing. Only the direct probe -- exactly what the guide's example tells readers to write -- saw it. The new test asserts the ordering rather than the value: it calls each predicate as the first method on the object. It fails on the unfixed code with "expected: <true> but was: <false>" and passes after. Full core-unittests suite: 6078 tests, 0 failures. SpotBugs regenerated: 0. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Compared 151 screenshots: 151 matched. Native Android coverage
✅ Native Android screenshot tests passed. Native Android coverage
Benchmark ResultsDetailed Performance Metrics
|
Compared 181 screenshots: 181 matched. |
Uh oh!
There was an error while loading. Please reload this page.
✅ ByteCodeTranslator Quality ReportTest & Coverage
Benchmark Results
Static Analysis
Generated automatically by the PR CI workflow. |
The developer guide shipped four structural defects that every existing gate passed. All four are reproducible by rendering the book and reading the result back, which is what the new checks do.
What was broken
"Working with the native Linux port" was not in the manual. Its include sat on the line directly after
Working-With-Windows.asciidoc, whose last line is a paragraph, so after include expansion the Linux chapter's title became a continuation of that paragraph. The whole chapter rendered as sections 94.9–94.13 of the Windows one. Asciidoctor reports nothing for this.Three chapters were rendering as book parts.
Accessibility-Semantics,MCP-Headless-APIandMedia-And-Audioopened with a level-0 heading; underdoctype: bookthat makes each a part, promotes its own sections to chapters and deletes its title from the sequence. Twenty-two of the book's "chapters" were really sections of those three.Six documents were included by nothing.
component-selector.asciidoc(the liveComponentSelectorAPI),SVG-Transcoder.asciidocandVideo-Capture-Constraints.asciidocare now in the book.Casual-Game-Programming.asciidocis superseded by the card-game case study in Game Development and is deleted with its two images;cn1libs.asciidocwas an "under construction" stub;Home.asciidoc's live links move into the preface.Eight cross-references pointed at ids that do not exist. Asciidoctor renders
<<missing,Some words>>as an ordinary link to nowhere, so these looked fine in the output. The Application Lifecycle sidebar the introduction cites twice was written all along — it just had no anchor.Sixteen links to
codenameone.com/manual/<chapter>.html. The site serves/manualand/manual/exactly, with no splat, so every one 404s. Each sat inside an HTML/PDF fork whose commented-out PDF branch was already the internal xref that renders correctly in both backends, so the fork is collapsed onto it.Also: the ~90 chapters are grouped into parts, and
Index.asciidoc— which is the introduction, not an index — is renamed.New gates
Each was verified to fail when the defect it describes is reintroduced, and to pass again when it is reverted.
check-guide-structure.pycheck-guide-xrefs.py[some-id]check-missing-code-blocks.pycheck-guide-links.py_redirectsand the Hugo content tree rather than a hand-written listThe last two carry shrinking baselines, in the shape of
scripts/cast-semantics-baseline.txt.check-missing-code-blocks.pyrecords 409 existing holes. They come frombbdc6058f0("Extract developer guide snippets into demos"), which converted inline listings toinclude::directives and dropped a large number of them, leaving the introducing sentence, its colon and two blank lines.Commerce.asciidocdocuments a paid service and has no code at all; it had four blocks when it was added. Sampling 120 baseline entries againstbbdc6058f0~1finds a block directly after the sentence in 119 of them, so the signature is sound and the originals are recoverable. Filling those holes is the next change, not this one.Verification
Locally green: asciidoctor at
--failure-level WARN, Vale 0/0/0, LanguageTool 0 matches withstatus: okunder JDK 17, paragraph capitalization, unused images, and 738 validated snippet blocks. The one snippet touched here compiles againstmaven/core/target/classes.