docs(readme): rewrite README with badges, real inventory and a usage guide - #8
Merged
Conversation
Add the offline EN->PT-BR translation capability (LLamaSharp local inference, GGUF model download, hash-based translation cache, resumable BookTranslationJob, translated EPUB export) to Funcionalidades, plus the Windows-only caveat pointing at the llm-mobile phase. Replace the vague "claro/escuro" theme claim with the real Light/Dark/Sepia set delivered by ThemeEngine, drop the Bookmarks bullet (the feature has no Manager surface nor UI yet), and pin real package versions in Stack. Refs: D-2026-07-29-readme-1 (b), (i), D-2026-07-29-readme-3 Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
The Componentes table showed 6 of the 16 services that actually exist. Add the 10 missing ones (TranslationManager, SettingsManager, TranslationEngine, ThemeEngine, SettingsAccess, TranslationCacheAccess, ModelAccess, BookTranslationJobAccess, PromptUtility, HtmlUtility), reusing the component descriptions from CLAUDE.md verbatim so the two documents cannot drift. Redraw the layer diagram with the Managers/Engines split and all three utilities, state the closed call rules, and extend Casos de Uso with the settings and translation flows. Refs: D-2026-07-29-readme-1 (c) Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
The Estrutura do Projeto block described a single project with Contracts/Business/Access/Models nested under src/TranslateReader, and listed BookDetailPage.xaml / BookDetailPageModel.cs, which do not exist. Replace it with the real tree: TranslateReader.Core (net10.0 library), TranslateReader (MAUI app) and TranslateReader.Tests. Drop the gitignored .idea/ entry and add the .github/.jdi folders that do exist. Add a Roadmap section that marks every unbuilt item as planned and maps it to its JDI phase slug, so BookDetailPage, bookmarks and mobile LLM support are documented as future work instead of shipped features. Refs: D-2026-07-29-readme-1 (d), (e), (h) Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Settings, TranslationCache and BookTranslationJob were missing entirely. Add them with the fields the ResourceAccess implementations actually create, including the UNIQUE(BookId, ChapterHRef, OriginalHash) constraint that makes the translation cache work and the LastCompletedChapterIndex resume point, and note that Bookmark has no UI yet. Refs: D-2026-07-29-readme-1 (g) Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Solution-level "dotnet build -f <TFM>" fails with NETSDK1005 because TranslateReader.Core and TranslateReader.Tests target plain net10.0. Point every build/run command at the app csproj instead and explain why. Add a Testes e Cobertura section with the real test command lines (the same ones ci.yml runs) and the 90% rule for code after boundary 4285f25, stating explicitly that the automated gate is planned in the cobertura-e-ci phase and is not enforced today. Add a Contribuindo section pointing at CLAUDE.md, the JDI workflow and the C# rules. Refs: D-2026-07-29-readme-1 (f), D-2026-07-29-readme-4 (2), (3), D-6 Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
"Licenca: Projeto privado" was false — the repository is public and ships an Apache License 2.0 file. Replace it with the real license and a link. Add a Seguranca section: the private reporting path from SECURITY.md, a table of the eight scanners wired into pipeline.yml (each mapped to a workflow file that exists), the supply-chain hardening rules (third-party actions pinned by full commit SHA, least-privilege permissions, harden-runner) and the untrusted-input boundaries the code enforces. Refs: D-2026-07-29-readme-1 (a), D-2026-07-29-readme-4 (1), (4) Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Pipeline, CodeQL, OpenSSF Scorecard, SonarCloud Quality Gate, SonarCloud Coverage, License Apache 2.0 — build health, then security scanners, then supply-chain score, then quality, then license. CodeQL gets its own badge rather than being folded into Pipeline: codeql.yml also runs on a weekly cron, outside the orchestrator graph. Every Actions badge points at a workflow file that exists in .github/workflows/. All six URLs verified resolvable (HTTP 200). Refs: D-2026-07-29-readme-2 Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
All 7 tasks completed, one commit each, single-writer sequential as the plan required. Full DoD battery re-run from the repo root after the last README commit: 10/10 auto-verifiable items pass, all six badge URLs resolve (HTTP 200), test baseline unchanged (169 passed, 2 skipped). Four deviations recorded in SUMMARY.md, the notable one being that the badge resolvability probe had to switch from HEAD to GET: SonarCloud answers 405 to HEAD on /api/project_badges/measure, so the plan's "curl -sfI" failed for a reason unrelated to badge validity. The gate stayed hard and still passes. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Review iteration 1 flagged three sentences that turned RULES (from .claude/rules/csharp.md and the Semgrep ruleset) into DESCRIPTIONS of behaviour the code does not have. All three are prose in the same file and are one coherent change -- stop claiming things the repo does not do -- so they ship as a single commit. B-1 (security, the serious one): the Seguranca section claimed the code validates path escape and bounds decompressed size when extracting EPUB zip entries. It does not. ReadingManager.cs:59-60 builds the output path straight from EPUB-derived input and FileUtility.cs:31-32 writes it with no containment check and no size bound; there is no ExtractToFile / entry.FullName / Path.GetFullPath guard anywhere in src/. The section now describes what actually exists: the normative rule in .claude/rules/csharp.md section 4, and the four custom Semgrep rules in .semgrep/dotnet-security.yml framed explicitly as CI DETECTION rules, not runtime defenses. The real code gap is recorded in .jdi/todos.md. B-2 (tests): "isolados: sem rede, sem disco e sem SQLite real" was false on two of three clauses -- FileUtilityTests, ModelAccessTests, ParsingEngineTests and HybridWebViewContractTests touch real disk, and InMemoryDatabase.cs:19 opens a real Microsoft.Data.Sqlite connection. Now describes the suite as measured (171 tests, 169 passing, 2 skipped for a missing GGUF model; in-memory SQLite and temp-dir IO where the unit under test is the resource access itself) and attributes the isolation rule to .claude/rules/csharp.md section 6 as a convention for NEW code. B-3 (pipeline topology): the table sat under "pipeline.yml dispatches the reusable workflows below" and included scorecard.yml, which pipeline.yml never dispatches and which has no workflow_call at all. The table now lists the 8 jobs pipeline.yml really dispatches, with their real triggers (dependency-review on PR only, sbom on push only), and scorecard.yml plus release.yml moved to a separate table of independent workflows with the reason each stays out. W-1: the Android build line failed NETSDK1005 on a machine without an Android SDK, because TranslateReader.csproj:7 only adds the android TFM when one is detected. The line now carries that precondition, a dedicated callout explains it, and the pre-existing solution-level NETSDK1005 callout is relabelled so a reader hitting the Android error is no longer sent to the wrong explanation. Adds the msbuild -getProperty command to list the TFMs actually available on the current machine. Every retained sentence in the touched sections was re-verified against the repository before commit. DoD 10/10, badges 6/6 GET 200, no accented characters, dotnet test 169 passed / 2 skipped. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
SUMMARY.md gains a "Fix round 1" section documenting iteration 2: for each of the three blockers, what the README falsely claimed, the file:line evidence that disproved it, and what the text says now. Also records the common root cause (iteration 1 converted rules from .claude/rules/csharp.md and the Semgrep ruleset into descriptions of existing behaviour), the W-1 fix, the full validation battery, and the REVIEW warnings deliberately left untouched. todos.md gains an entry for the finding B-1 exposed: EPUB image extraction has no path containment and no decompressed-size bound, which .claude/rules/csharp.md section 4 requires. Evidence is ReadingManager.cs:59-60 plus FileUtility.cs:31-32, with the grep results showing no guard exists anywhere in src/. Notes that the translatereader-zip-slip Semgrep rule does not match this call site -- it patterns on Path.Combine($DEST, $ENTRY.FullName) while the real code goes through an intermediate variable from the VersOne.Epub API -- so CI gives false confidence here. Candidate for a hardening phase. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
W-10: the Disparo column noted an own weekly cron only on the CodeQL row, implying the other jobs had none, and called SBOM "somente push" while it also runs on its own Tuesday cron. Read the on: block of all 8 reusable workflows and made the column uniformly accurate: codeql (Mon 07:26 UTC), semgrep (Mon 06:45), sca (Wed 05:50), secret-scan (Sun 04:15) and sbom (Tue 03:20) declare schedule + workflow_dispatch besides workflow_call; ci, sonarqube and dependency-review declare workflow_call only. W-11: re-admit as its own sentence the claim that every book-derived value is encoded before reaching JavaScript. All 10 EvaluateJavaScriptAsync call sites in ReaderPage.xaml.cs were audited: chapter HTML, chunks and HRef go through JsStr (:486, JsonSerializer.Serialize), translated paragraphs arrive pre-serialized (:305-306), and the rest are constant scripts and internal function-name literals. The Semgrep rule sits at WARNING because the pattern cannot prove the two sites that bypass the helper - a detector limit, not a code hole. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Round-2 judgement: the README was precise enough to understand and build the project but never taught anyone to use the app, and in particular never said that translation requires downloading a GGUF model through the app first. Adds a usage section grounded in the source: import via the Importar toolbar item and the platform EPUB filters (LibraryPageModel.ImportBookAsync); the library grid with cover, progress bar and the Traduzir livro / Excluir context menu (LibraryPage.xaml); reader settings - theme, scroll vs paginated, font and spacing, source/target language - applied live and saved on panel close (SettingsOverlay, ReaderPage.xaml.cs OnSettingsCloseRequested); reading position saved on disappear and restored on open (ReaderPageModel.InitializeAsync); and the translation flow - automatic download of gemma-2-2b-it-Q4_K_M.gguf (TranslationManager.DefaultModel), visible-paragraph translation via the Aa button which is paginated-mode only, resumable full-book jobs producing a new EPUB, and the SHA-256 translation cache. Repeats the Windows-only inference caveat from phase llm-mobile. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Appends a Fix round 2 section covering the autonomous warning-fix pass: W-10 (CI trigger table), W-11 (WebView encoding claim) and the missing usage section. Each entry states the warning, the fix, and the file:line evidence gathered before writing, plus the resulting commit hashes and the validation run. Also records the two capabilities left undocumented on purpose because the code does not back them. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
Security finding escalated from the readme phase: EPUB extraction lacks path containment and decompression bounds, and the Semgrep rule meant to catch it structurally cannot match the real call path. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
ReaderPageModel.IsModelAvailable is a session flag written only on download/load, never a disk check, and the PageModel is transient — the button hides after a restart even with the model on disk. Also corrects the superseded Semgrep diagnosis in todos.md and records the dead model picker as an adjacent UI/code finding. Claude-Session: https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Phase
readmeshipped via JDI autonomous chain (/jdi-issue).Source: pasted card — "Melhore o Readme.md do projeto, adicione as badges deixe bem explicado."
Verdict: APPROVED_WITH_WARNINGS (verify round 3) · Loop: 3 iterations, 0 auto-resets, 2 fix rounds
Base: targets
jdi/pipeline-unificada(PR #7) because the pipeline badge points atpipeline.yml, which only exists there. Merge #7 first, then this collapses ontomain.What changed
Six badges (Pipeline, CodeQL, OpenSSF Scorecard, Sonar quality gate, Sonar coverage, Apache-2.0) — all verified HTTP 200, none citing a workflow file that doesn't exist.
The card asked for badges and clarity; the audit found the README was also factually wrong in nine places, so the phase fixed those too:
LICENSECore, app, tests)BookDetailPage/BookDetailPageModeldocumented as existing — they don't; moved to a Roadmap section pointing at phasedetalhe-livro-f <TFM>, which failsNETSDK1005Settings,TranslationCache,BookTranslationJob.idea/; themes said light/dark butThemeEngineships Sepia tooNew sections: Como usar (import → read → settings → translation, including the 1.6 GB GGUF download users hit before their first translation), security, tests, contributing/JDI, license.
Review caught three false claims I wrote
Round 1 came back BLOCKED. In writing the security, tests and CI sections I had converted rules from
.claude/rules/csharp.mdand the Semgrep ruleset into descriptions of what the code already does:pipeline.ymldispatchesscorecard.yml— it dispatches 8 jobs, and scorecard has noworkflow_callat allAll three fixed, plus a later round corrected the CI trigger table (SBOM was labelled "push only" but has its own Tuesday cron) and scoped the delete-model button claim to session state.
Security finding escalated out of this phase
Verifying claim #1 exposed a real gap, now registered as phase
epub-zip-slip(D-2026-07-29-epub-zip-slip-1):ReadingManager.cs:59-60builds the output path from EPUB-supplied content and hands it toFileUtility.cs:31-32, which writes with no containment check and no size bound — untrusted input, violating.claude/rules/csharp.md§4.Worse: the custom Semgrep rule meant to catch exactly this structurally cannot fire on it. The rule requires syntactic access to
.FullName; the project extracts through VersOne.Epub and never touchesZipArchiveEntry. Proven with a 4-case probe — canonical patterns detected, the real call path not. The phase therefore locks two deliverables: the code fix and the rule fix, because shipping only the first leaves the defect invisible to CI.Shipped with warnings
Nine open, none blocking. Notable:
IsModelAvailableis a session flag so the delete-model button vanishes after restart despite 1.6 GB on disk; the settings model picker writesTranslationModelNamethat nothing consumes; model download is not resumable. All three recorded in.jdi/todos.mdas a UI-promises-code-doesn't-honor cluster — the same defect class this phase spent three rounds purging from the README, but on screen.Deferred to PR review
Badge rendering after merge · the subjective "bem explicado" judgment · SonarCloud dashboard values · screenshots (none exist yet).
https://claude.ai/code/session_01BSdgwqZVLeiZfYsGNQ4V9i