${esc(s.title)}
${esc(s.text.slice(0,200))}${s.text.length>200?'…':''}
diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 4c0bca8..7f82269 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -40,6 +40,7 @@ jobs: - run: python scripts/ui_studio_smoke.py - run: python scripts/ui_science_smoke.py - run: python scripts/ui_graphify_smoke.py + - run: python scripts/ui_polemic_smoke.py - uses: actions/upload-artifact@v4 if: always() with: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index 6574fa6..d466db3 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -20,6 +20,7 @@ jobs: - run: python scripts/ui_studio_smoke.py - run: python scripts/ui_science_smoke.py - run: python scripts/ui_graphify_smoke.py + - run: python scripts/ui_polemic_smoke.py windows: needs: quality runs-on: windows-latest @@ -37,7 +38,7 @@ jobs: GITHUB_TOKEN: ${{ github.token }} run: ./scripts/build_release.ps1 - name: Exercise the actual Windows window, native dialogs and save-on-close - run: python scripts/native_smoke.py --science --graphify --executable dist/GraphPaper/GraphPaper.exe --out test-results/native-package + run: python scripts/native_smoke.py --science --graphify --polemic --executable dist/GraphPaper/GraphPaper.exe --out test-results/native-package - uses: actions/upload-artifact@v4 with: name: GraphPaper-Windows-x64 @@ -53,7 +54,7 @@ jobs: $version = python -c "from graphpaper import __version__; print(__version__)" if ($env:GITHUB_REF_NAME -ne "v$version") { throw 'Tag does not match application version.' } gh release view $env:GITHUB_REF_NAME *> $null - if ($LASTEXITCODE -ne 0) { gh release create $env:GITHUB_REF_NAME --verify-tag --title "GraphPaper $env:GITHUB_REF_NAME" --notes-file docs/RELEASE-0.3.1.md } + if ($LASTEXITCODE -ne 0) { gh release create $env:GITHUB_REF_NAME --verify-tag --title "GraphPaper $env:GITHUB_REF_NAME" --notes-file docs/RELEASE-0.4.0.md } $packageName = "GraphPaper-v$version-Windows-x64.zip" $release = gh release view $env:GITHUB_REF_NAME --json assets | ConvertFrom-Json if ($release.assets.name -contains $packageName) { diff --git a/CHANGELOG.md b/CHANGELOG.md index 89fa623..b497b12 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## 0.4.0 + +- Add Polemic and a reversible writing-mode switch for existing projects. +- Separate thesis, writing purpose, rhetorical force and evidence detail; remove unconditional neutrality/counterargument pressure. +- Supply author voice and intention to angle selection, JEV scoring, outlining, review, revision and prose polishing. +- Draft short argumentative pieces as coherent wholes rather than restarting the same disclaimers for each section. +- Track stale angle/outline/review context; refresh angles without rebuilding the graph; flag stance drift as a meaning change. +- Preserve source checks, native Windows fixes, Graphify/Codex, Science/APA, project folders and existing manuscripts. + + ## 0.3.1 - Repair external Graphify extraction with the configured provider, including official Codex OAuth and extraction-role reasoning. diff --git a/README.md b/README.md index 7685b06..c475b95 100644 --- a/README.md +++ b/README.md @@ -21,17 +21,18 @@ Changelog
-GraphPaper is a **local-first writing studio for nonfiction, fiction and scientific manuscripts**. Upload your material, explore its knowledge graph, choose a direction, shape the outline and refine the draft—all in a Windows desktop interface. +GraphPaper is a **local-first writing studio for nonfiction, fiction, polemic and scientific manuscripts**. Upload your material, explore its knowledge graph, choose a direction, shape the outline and refine the draft—all in a Windows desktop interface. -Use **Codex / ChatGPT sign-in** or your own model API. Keep control of the argument, the evidence and the final words. +Use **Codex / ChatGPT sign-in** or your own model API. Keep control of the argument, the evidence and the final words. **Polemic and argument-led nonfiction preserve your thesis and voice across angle selection, outlining and review.** [Continue an existing project in Polemic](docs/POLEMIC.md). **External Graphify now supports Codex sign-in and per-model reasoning.** The Windows release includes the public runtime; there is no extra API-key requirement or duplicate Native pass. [Graphify setup and distribution](docs/UPDATE-0.3.1.md) -## Three ways to write +## Four ways to write | Mode | Start with | Build toward | |---|---|---| | **Nonfiction** | Articles, documents, notes and a question | A distinctive, source-linked essay or article | +| **Polemic** | A position, your reasoning and your own writing voice | An argument with conviction, wit and factual precision—not compulsory balance | | **Fiction** | A premise, characters and the rules of your world | Scene-driven writing with a continuity ledger | | **Science** | A research question and an explicit search protocol | An evidence-led manuscript, APA references and an auditable research package | diff --git a/docs/GRAPH-AND-JEV.md b/docs/GRAPH-AND-JEV.md index 4baf398..cc30d87 100644 --- a/docs/GRAPH-AND-JEV.md +++ b/docs/GRAPH-AND-JEV.md @@ -56,3 +56,7 @@ With JEV off, structural exploration still works and results are not given fabri After adding, changing, excluding or reclassifying sources, rebuild before relying on graph coverage. Scientific screening can change the enabled evidence set as well. Inspect important connections again when their underlying material changes. A stronger graph is useful only if it leads to a better argument or story. The [quality protocol](QUALITY.md) separates that editorial question from the fact that the software tests passed. + +## Argument-led angle discovery + +Polemic generates alternative routes into your thesis, not alternative opinions on whether you may hold it. JEV now receives the author voice and editorial contract and scores stance/voice fidelity explicitly. Counterarguments are optional and must be directly consequential. Brief or voice changes mark old angles as stale; refresh them without re-running Graphify. [Authorial-intent controls](POLEMIC.md). diff --git a/docs/NONFICTION.md b/docs/NONFICTION.md index ea377d2..2a5dad5 100644 --- a/docs/NONFICTION.md +++ b/docs/NONFICTION.md @@ -2,13 +2,13 @@ Use Nonfiction for essays, reports, cultural analysis and source-led articles. Choose [Science](SCIENCE.md) instead when you need scholarly database searching, a recorded screening process and academic manuscript exports. -## Start with a question, not a compulsory conclusion +## State the purpose: argue or explore -In the Creative brief, specify the audience, format, voice, target length and the issue you want to investigate. A productive direction leaves room for the sources to surprise you: +Nonfiction is not automatically a neutral survey. State what the piece should do in the Creative brief: investigate an open question, develop an interpretation, defend a position or make a criticism. **Writing purpose** can follow the brief, explicitly preserve your position, or explore without a predetermined verdict. -> Explore when public lighting serves safety and when it intrudes on private rest. Address the strongest argument for brighter streets. +Use **Core thesis** for a proposition you want preserved, or leave it blank to use Direction. Your enabled voice samples now guide angle selection and outlining as well as prose. Factual checks can correct a premise without deciding that the author should hold a more moderate opinion. -This is a suggested brief, not a factual claim about lighting research. The included nonfiction demo uses invented illustrative notes; replace them with real evidence before publication. +For explicitly polemical essays, satire and opinion, choose [Polemic](POLEMIC.md). An existing project can switch modes without replacing its sources or graph. The distinction is the job you are asking the writer to do, not permission to invent facts. ## Prepare the source library @@ -34,7 +34,7 @@ Read the thesis, counterargument, evidence links and unresolved questions. Use * Each section should change what the reader understands. Edit its purpose, beats and planned word count, and reorder sections before drafting. Source IDs make it possible to return to the material behind a section. -The writer produces sections sequentially and then reviews the whole draft. The context contains selected relevant passages and prior prose, not necessarily the whole corpus on every call. Avoid interpreting a complete-looking article as evidence that every source was read in full at every stage. +Explicitly argument-led outlines up to 3,000 words are drafted as one coherent piece, then reviewed. Other nonfiction uses sequential sections followed by a whole-draft review. The context contains selected relevant passages and prior prose, not necessarily the whole corpus on every call. Avoid interpreting a complete-looking article as evidence that every source was read in full at every stage. ## Edit, verify, export diff --git a/docs/POLEMIC.md b/docs/POLEMIC.md new file mode 100644 index 0000000..d2aa765 --- /dev/null +++ b/docs/POLEMIC.md @@ -0,0 +1,58 @@ +# Polemic, argument and authorial intent + +Use **Polemic** for an essay that argues a position: moral criticism, satire, cultural argument, an opinion piece or a sharply reasoned indictment. It is the fourth writing mode, alongside Nonfiction, Fiction and Science. + +The mode does not choose an opinion for you. It develops yours. Factual precision remains necessary; automatic neutrality does not. + +## Continue an existing project + +You do **not** have to create a new project, re-upload your writing samples or rebuild the graph. + +1. Open the project and click **Nonfiction · Change** (or the current mode name) near the top. +2. Select **Polemic** and apply the change. +3. Open **Creative brief**. Set your **Core thesis / position to preserve** and **Rhetorical force**. The thesis is optional: when blank, the writer follows your existing Direction field. +4. In **Angles**, click **Refresh angles with my voice**. This reuses the current graph and enabled voice samples. It does not run another graph extraction. + +Sources, source IDs, graph, voice profile, draft, outline, previous angles and draft versions stay in the same project when you change its mode. Old generated angles are not silently rewritten by moving a slider. The interface marks angles or outlines made under an earlier brief/voice as out of date and offers an explicit refresh. Existing manually chosen work remains yours to retain or edit. + +## Three different controls + +**Writing purpose** determines the task. Polemic develops and defends the stated position. Ordinary Nonfiction now also supports **Develop and defend my position**, **Investigate an open question**, or **Follow the brief**. A question-led article need not conclude in the center either: its conclusion should follow its reasoning and evidence. + +**Rhetorical force** controls delivery: understated, pointed or uncompromising. It does not increase factual certainty, mechanically add swear words, or replace your voice with a generic aggressive style. + +**Evidence detail** controls how extensively the piece develops its factual basis and directly relevant limits. It is not a politeness, neutrality or permission-to-invent slider. Lower detail keeps the presentation lean; higher detail supports a fuller treatment without demanding a yes-but paragraph after every judgment. + +A precise brief names the proposition, not only the tone. For example: + +> Argue that the policy rewards appearances instead of results. Make the case through its incentives, its language and the experience of the people subjected to it. Preserve the satire and end with the judgment. Check factual claims, but do not turn the argument into an open question about whether criticism is permissible. + +## What changed in 0.4 + +Previous versions supplied the author voice to drafting/revision but omitted it from angle generation, outline generation and the initial editorial review. At the same time, shared prompts repeatedly emphasized counterarguments and moderation-adjacent phrasing. Those two choices could select a neutralized thesis before the writer ever encountered the author's voice. + +The editorial pipeline now receives a common **authorial contract** and the voice context at angle generation, JEV candidate evaluation, final angle scoring, outlining, drafting, review, revision and prose polishing. Voice samples remain stylistic evidence, not factual sources. + +The angle stage generates different routes into the requested argument rather than different degrees of retreat from it. A counterargument is optional metadata and must be relevant; an empty field is better than a manufactured objection. Candidate scoring considers **stance fidelity** and **voice fidelity** alongside factual support and editorial potential. Without JEV, the same authorial contract still goes to the language model. + +The critic distinguishes factual assertions, inferences, moral judgments, analogies, satire and deliberate hyperbole. A moral description of conduct is not automatically a clinical diagnosis. Conversely, an invented diagnosis or factual allegation is not excused by choosing Polemic. The editor should identify the actual problem and suggest a local repair, not replace the entire position with something milder. + +## Avoiding repeated disclaimer openings + +Short polemics and explicitly argument-led nonfiction with an approved outline of **up to 3,000 words** are drafted as one coherent piece. Section-by-section generation could repeatedly reopen the same uncertainty because every section saw the same cautionary instructions afresh. + +Longer pieces retain section-wise drafting, with the same authorial contract and prior prose. Fiction keeps its scene/continuity workflow; Science keeps its scientific research workflow. The whole-piece writer still receives the approved outline and selected source passages and is followed by the usual evidence review. + +## Voice and editing + +Enabled current writing samples reach the angle stage even when a learned profile needs refreshing. A stale learned profile is not treated as current, and turning voice influence off is still respected. Voice learning now explicitly attends to rhetorical moves, willingness to conclude, analogy, comic timing, indignation and argument structure—not just sentence length and punctuation. + +The review panel can report **authorial fidelity** separately from source support. It can flag an irrelevant caveat or a softened conclusion as editorial drift. Automatic revision acceptance is asked to preserve thesis, force and voice; a more moderate or polite result is not automatically a better result. + +Humanize and Deslop follow the same intent. Their fidelity critic also sees the brief and voice. A changed stance counts as a meaning warning, and a candidate prepared under an earlier brief or voice cannot silently overwrite the current draft. + +## Scope + +This is an editorial-workflow change, not a switch that rewrites a provider's behavior or guarantees a particular style from every model. Inspect the proposed angles and choose your own when appropriate. The release includes wiring, preservation, UI and native regression tests plus separately labelled live Codex examples using original synthetic material. The fixtures are not a user's private articles and are not empirical findings about AI consciousness. + +[Nonfiction workflow](NONFICTION.md) · [Author voice](VOICE-AND-PROSE.md) · [Graph and JEV](GRAPH-AND-JEV.md) · [Validation](QUALITY.md) diff --git a/docs/QUALITY.md b/docs/QUALITY.md index 9abc5cf..614a443 100644 --- a/docs/QUALITY.md +++ b/docs/QUALITY.md @@ -1,5 +1,15 @@ # Validation and quality +## Version 0.4.0 validation + +**252 automated Windows tests passed**; 1 permission-related test skipped. All **54 real-HTTP browser checks** passed, with no JavaScript page errors. The actual compiled Windows application passed **17 native checks**, including mode conversion, thesis/force controls, external Graphify, native Save As and pending-edit save before normal exit. + +The packaged Python code for the changed modules was compared with the final source as semantic code objects; all UI assets were compared byte-for-byte. The Windows package includes the previously verified public Graphify and official Codex runtimes. No installed user project was changed. + +A live Codex test generated argumentative angles from original synthetic evidence and voice samples, then drafted and reviewed a complete short argument. A separate opposing-position test confirmed the editorial policy does not choose which side the author should support. The first outline response was malformed JSON and was rejected; the successful continuation was a manually restarted test using the saved angles. No live JEV call or new user sign-in ceremony was performed. Deterministic tests inspect JEV voice/stance inputs separately. + +The tests validate behavior and handoff, not a universal promise of perfect style or zero caveats. Source, browser, native, package and live-test evidence is under [validation/v0.4.0](validation/v0.4.0/). Other-platform results, when available, are the actual hosted CI results rather than inferred Windows coverage. Earlier reports below are historical. + ## Version 0.3.1 validation 217 automated Windows tests passed (1 platform-permission skip). All 44 browser workflow checks passed, all 10 native-source checks passed, and all 15 checks against the actual compiled executable passed. The compiled-native checks include a real public Graphify worker with synthetic model transport, source provenance, native Save As and save-on-close. diff --git a/docs/README.md b/docs/README.md index 95668ef..7719e38 100644 --- a/docs/README.md +++ b/docs/README.md @@ -2,7 +2,7 @@ **A studio for connected thought.** GraphPaper brings source material, graph exploration and a writing desk into one local-first Windows application. -These guides describe **GraphPaper 0.3.1**. The [release page](https://github.com/AronAxe/GraphPaper/releases/latest) provides the current Windows download; [CHANGELOG](../CHANGELOG.md) records version history. The same guides are published in the [GitHub wiki](https://github.com/AronAxe/GraphPaper/wiki). +These guides describe **GraphPaper 0.4.0**. The [release page](https://github.com/AronAxe/GraphPaper/releases/latest) provides the current Windows download; [CHANGELOG](../CHANGELOG.md) records version history. The same guides are published in the [GitHub wiki](https://github.com/AronAxe/GraphPaper/wiki). ## Start here @@ -12,6 +12,7 @@ These guides describe **GraphPaper 0.3.1**. The [release page](https://github.co | Upgrade Windows or use the source edition | [Windows installation](WINDOWS.md) | | Use ChatGPT sign-in, API models or deeper reasoning | [Models and reasoning](CONNECTIONS.md) | | Write an essay or researched article | [Nonfiction workflow](NONFICTION.md) | +| Make a forceful argument without forced neutrality | [Polemic and authorial intent](POLEMIC.md) | | Develop a story and preserve its canon | [Fiction workflow](FICTION.md) | | Search scholarly literature and write a manuscript | [Science workflow](SCIENCE.md) | diff --git a/docs/RELEASE-0.4.0.md b/docs/RELEASE-0.4.0.md new file mode 100644 index 0000000..73afa2f --- /dev/null +++ b/docs/RELEASE-0.4.0.md @@ -0,0 +1,37 @@ +# GraphPaper 0.4.0 — keep the author's argument + +## Fixed: forced moderation of the writing + +Angle generation no longer defaults to counterbalancing every position or turning a judgment into an open question. Author voice and a common authorial contract now reach **angle discovery, JEV evaluation, outline generation, drafting, review, revision and Humanize/Deslop**. + +The critic checks facts without treating moral judgments, satire or rhetorical force as defects. A softened conclusion or an irrelevant caveat can be flagged as authorial drift. A more moderate or polite revision is not automatically a better revision. + +## New: Polemic, the fourth writing mode + +Polemic develops and defends the author's position. Different angles are different ways into the argument, not different degrees of retreat from it. Ordinary Nonfiction also supports an explicitly argument-led purpose; this is not only a new label. + +**Core thesis**, **Writing purpose**, **Rhetorical force** and **Evidence detail** are separate controls. Lower evidence detail means leaner presentation, not fabricated facts. Higher detail does not request ideological balance. Polemic does not mechanically add profanity or replace the author's own voice with a generic aggressive style. + +Short argumentative outlines up to 3,000 words are drafted as one coherent piece, avoiding repeated disclaimer openings caused by restarting the writer for every section. Longer writing, fiction continuity and the Science workflow remain available. + +## Continue your current project + +Open the existing project, choose **current mode · Change → Polemic**, and edit **Creative brief → Core thesis / Rhetorical force**. In Angles, choose **Refresh angles with my voice**. + +**Do not rebuild the graph merely to change the writing stance.** The mode change preserves the source library, graph, voice profile, manuscript and prior generated work. Old angles do not rewrite themselves when a slider changes; they are marked stale until explicitly refreshed or edited. + +## Windows package + +Download **GraphPaper-v0.4.0-Windows-x64.zip**, extract the complete folder, and run **GraphPaper.exe** with `_internal` beside it. This portable build is unsigned. The included public Graphify runtime, Codex OAuth, reasoning controls, Science/APA, project folders and native freeze/save-on-close fixes remain in the package. + +## Verification and scope + +Regression tests cover intent and voice handoff at each stage, both opposing author positions, stale-context detection, existing-project preservation, polishing fidelity and source-reference export. Browser/native checks exercise the actual controls. Live Codex editorial examples use original synthetic documents and a synthetic voice sample, not private user articles; evidence for wiring is distinct from a universal prose-quality guarantee. + +See [Polemic and authorial intent](https://github.com/AronAxe/GraphPaper/blob/main/docs/POLEMIC.md) and the versioned validation reports for exact test counts, platform results and live-test scope. SHA256SUMS.txt identifies the downloadable archive. + +## Verified artifact + +252 automated Windows tests passed (1 permission-related skip), all 54 browser checks passed, and all 17 checks passed against the actual compiled executable. Live Codex editorial tests used original synthetic material; JEV input behavior was tested without live JEV spending. + +Windows ZIP: **187,529,591 bytes**. SHA-256: `c9fb03c6b293b8505b14ec427c7266aba1e3be8f0391be35ecead18a91399b53`. diff --git a/docs/TROUBLESHOOTING.md b/docs/TROUBLESHOOTING.md index fa0ec00..52234ac 100644 --- a/docs/TROUBLESHOOTING.md +++ b/docs/TROUBLESHOOTING.md @@ -62,3 +62,7 @@ A network timeout can represent a request the provider already processed. The ap Open a [GitHub issue](https://github.com/AronAxe/GraphPaper/issues) with the version, source-versus-executable edition, exact action, error text and a small non-confidential example when possible. Say whether the failure occurs in an empty project and which provider/model is involved—without including keys. Review diagnostics before sharing them. Never attach `credentials.dpapi`, Codex account files, a private manuscript or an unredacted data-directory archive. Security-sensitive disclosures should go privately to the maintainer, not into a public issue. [Privacy and security →](SECURITY.md) + +## Angles are too cautious or ignore my voice + +Use the 0.4 release. It removes forced counterbalancing and supplies voice context to the early editorial stages. In an existing project, choose **current mode · Change -> Polemic**, then edit **Core thesis** and **Rhetorical force**. In Angles, choose **Refresh angles with my voice**; old saved angles do not rewrite themselves when a slider changes. The existing graph is reused. Evidence detail is a separate control and never sets how moderate your position must be. Ordinary Nonfiction can also **Develop and defend my position**. diff --git a/docs/VOICE-AND-PROSE.md b/docs/VOICE-AND-PROSE.md index f6e1e56..ed233c5 100644 --- a/docs/VOICE-AND-PROSE.md +++ b/docs/VOICE-AND-PROSE.md @@ -46,3 +46,7 @@ A lower cue count is not a quality score. The goal is a better passage with the ## Design references The independent implementation was informed by the writing-focused approaches in [blader/humanizer](https://github.com/blader/humanizer) and [stephenturner/skill-deslop](https://github.com/stephenturner/skill-deslop). No full third-party prompt or code is presented as GraphPaper’s own. Historical research notes are preserved in [the 0.2 update](UPDATE-0.2.md); star counts are not treated as permanent quality rankings. + +## Voice before the prose + +Since 0.4, voice samples and the authorial contract are supplied to angle generation, JEV evaluation, outlining and the initial reviewer as well as drafting and prose edits. Rhetorical stance, humor and willingness to conclude are part of authorial style, not merely punctuation. Moral judgments are distinct from factual claims. See [Polemic and argumentative writing](POLEMIC.md). diff --git a/docs/images/four-modes-v0.4.webp b/docs/images/four-modes-v0.4.webp new file mode 100644 index 0000000..005134b Binary files /dev/null and b/docs/images/four-modes-v0.4.webp differ diff --git a/docs/images/polemic-v0.4.webp b/docs/images/polemic-v0.4.webp new file mode 100644 index 0000000..e7b2bef Binary files /dev/null and b/docs/images/polemic-v0.4.webp differ diff --git a/docs/validation/v0.4.0/browser-base.json b/docs/validation/v0.4.0/browser-base.json new file mode 100644 index 0000000..6d7a759 --- /dev/null +++ b/docs/validation/v0.4.0/browser-base.json @@ -0,0 +1,25 @@ +{ + "mode": "HTTP browser", + "live_models": false, + "checks": [ + "Welcome and empty state", + "Illustrative graph renders with 18 nodes", + "Inspect graph node and persist pin", + "Path query and highlight", + "Edit and select an angle", + "Edit and reorder outline", + "Manuscript autosave and safe live preview", + "Clickable source references", + "Read and restore earlier version", + "Export options and valid Word output", + "Configure provider through UI (mock transport only)", + "Browser file-input upload and source ingestion", + "Complete graph \u2192 JEV \u2192 angle \u2192 outline \u2192 draft \u2192 review path with deterministic AI", + "Explicit revision job and versioning", + "Fiction from premise, scene generation and continuity ledger", + "Light theme", + "Responsive 390px layout without horizontal overflow" + ], + "page_errors": [], + "ok": true +} \ No newline at end of file diff --git a/docs/validation/v0.4.0/browser-graphify.json b/docs/validation/v0.4.0/browser-graphify.json new file mode 100644 index 0000000..0ea60ad --- /dev/null +++ b/docs/validation/v0.4.0/browser-graphify.json @@ -0,0 +1,24 @@ +{ + "real_http_browser": true, + "real_graphify_process": true, + "live_model": false, + "checks": [ + "Graphify runtime is available through the real graphical status check", + "External engine, extraction model and reasoning settings save from the interface", + "Build graph runs the actual external Graphify worker through the selected model and effort", + "Only evidence sources reach inference; no second Native extraction or uncounted request", + "External graph source provenance opens the correct original document" + ], + "page_errors": [], + "ok": true, + "extraction": { + "nodes": 3, + "edges": 2, + "model_requests": 1, + "runtime": "0.9.80", + "engine": "Graphify 0.9.80 via openai-compatible", + "reasoning": "high", + "model": "fixture-extractor", + "live_model": false + } +} diff --git a/docs/validation/v0.4.0/browser-polemic.json b/docs/validation/v0.4.0/browser-polemic.json new file mode 100644 index 0000000..a4b41db --- /dev/null +++ b/docs/validation/v0.4.0/browser-polemic.json @@ -0,0 +1,19 @@ +{ + "real_http_browser": true, + "live_model": false, + "synthetic_material": true, + "checks": [ + "Four distinct modes are available, including Polemic", + "Existing project converts to Polemic without replacing its sources, graph, voice or draft", + "Old angles are explicitly marked stale instead of pretending the brief rewrote them", + "Thesis, rhetorical force and evidence detail save as separate controls", + "Refreshing angles uses actual voice and intent inputs without rebuilding the graph", + "The outline receives the same author voice and argumentative contract", + "Drafting and the reviewer receive the authorial contract and report fidelity separately", + "Polemic retains normal citation and bibliography export", + "Argument-led intent also works in ordinary nonfiction; changing labels is not the sole fix", + "Controls fit a smaller desktop window" + ], + "page_errors": [], + "ok": true +} diff --git a/docs/validation/v0.4.0/browser-science.json b/docs/validation/v0.4.0/browser-science.json new file mode 100644 index 0000000..e201401 --- /dev/null +++ b/docs/validation/v0.4.0/browser-science.json @@ -0,0 +1,22 @@ +{ + "mode": "real HTTP browser", + "live_models": false, + "live_databases": false, + "checks": [ + "Four distinct writing modes on the welcome screen", + "Advertised Codex ultra and independent writer/editor/extractor efforts persist", + "Science project opens directly on the research desk", + "Research protocol, search terms, eligibility and APA author declarations save", + "Database search result cards carry metadata and access labels", + "Actual query, count and search status are visible in the audit log", + "Screened studies become correctly associated evidence sources", + "Full-text retrieval and source-quoted appraisal populate the evidence matrix", + "Scientific outline produces source-linked IMRaD manuscript and abstract", + "APA preview resolves author-year citations and references from metadata", + "APA Word export downloads an actual DOCX manuscript", + "Submission package requires author confirmation and rejects stale approval after edits", + "Research desk fits a smaller desktop window" + ], + "page_errors": [], + "ok": true +} diff --git a/docs/validation/v0.4.0/browser-studio.json b/docs/validation/v0.4.0/browser-studio.json new file mode 100644 index 0000000..792ea05 --- /dev/null +++ b/docs/validation/v0.4.0/browser-studio.json @@ -0,0 +1,17 @@ +{ + "mode": "real HTTP", + "live_models": false, + "checks": [ + "Voice sample upload through the actual file input", + "Learn, inspect and edit a persistent author voice profile", + "Project folder import and automatic source ownership", + "Idle folder watcher detects and imports new files without an AI call", + "Local explainable prose inspection", + "Humanizer proposal, side-by-side comparison and explicit acceptance", + "Separate deslopping pass and non-destructive rejection", + "Codex subscription provider selectable without an API key", + "New controls fit a smaller desktop window" + ], + "page_errors": [], + "ok": true +} \ No newline at end of file diff --git a/docs/validation/v0.4.0/codex-runtime.json b/docs/validation/v0.4.0/codex-runtime.json new file mode 100644 index 0000000..2e69cdb --- /dev/null +++ b/docs/validation/v0.4.0/codex-runtime.json @@ -0,0 +1,7 @@ +{ + "ok": true, + "version": "codex-cli 0.160.1", + "unauthenticated_app_server_handshake": true, + "live_model_call": false, + "browser_oauth_completed": false +} \ No newline at end of file diff --git a/docs/validation/v0.4.0/graphify-package.json b/docs/validation/v0.4.0/graphify-package.json new file mode 100644 index 0000000..700195b --- /dev/null +++ b/docs/validation/v0.4.0/graphify-package.json @@ -0,0 +1,53 @@ +{ + "platform": "Windows", + "python": "3.13.14", + "packaged_graphify_worker": true, + "real_graphify_process": true, + "live_codex": false, + "synthetic_project": true, + "ok": true, + "graphify_version": "0.9.80", + "job_state": "completed", + "usage": { + "calls": 1, + "input_tokens": 120, + "output_tokens": 90, + "reported_cost": 0.0, + "unpriced_calls": 0 + }, + "nodes": 3, + "edges": 2, + "coverage": { + "engine": "external_graphify", + "runtime_version": "0.9.80", + "runtime_selection": "bundled", + "sources": 2, + "characters": 146, + "source_ids": [ + "S1", + "S2" + ], + "model": "extract-fixture", + "reasoning_effort": "high", + "model_requests": 1, + "requests": [ + { + "call": 1, + "model": "extract-fixture", + "provider": "openai-compatible", + "reasoning_effort": "high", + "prompt_tokens": 120, + "completion_tokens": 90, + "total_tokens": 210 + } + ], + "scope": "Enabled source text exported in full; Graphify controls chunking and extraction. No extra Native extraction pass was run." + }, + "source_links": [ + "S1", + "S2" + ], + "voice_source_excluded": true, + "no_extra_native_pass": true, + "settings_preserved": true +} diff --git a/docs/validation/v0.4.0/live-codex-editorial.json b/docs/validation/v0.4.0/live-codex-editorial.json new file mode 100644 index 0000000..62ae8f9 --- /dev/null +++ b/docs/validation/v0.4.0/live-codex-editorial.json @@ -0,0 +1,451 @@ +{ + "scope": "Original synthetic evidence and voice sample, using an explicitly selected official Codex account. Not the author's private articles; no live JEV.", + "model": "gpt-6-luna", + "reasoning_effort": "low", + "angles": [ + { + "id": "a_f0576671593a", + "title": "The Smile Is the Story", + "thesis": "A demonstration that invites an audience to enjoy simulated suffering earns its sharpest moral judgment from the invitation itself. Whether the machine feels anything remains unresolved; the pleasure on display does not. Treating the uncertainty as a loophole turns ignorance into permission and makes the enthusiasm the indictment.", + "hook": "The machine’s experience was an open question. The audience’s invitation to enjoy its suffering was not.", + "why": "This route centers the moral disgust at entertainment built around apparent suffering, without pretending the scene proves machine consciousness.", + "motif": "directed chain", + "node_ids": [ + "uncertainty", + "enthusiasm", + "judgment" + ], + "edge_ids": [ + "e_ca0ed53f712d", + "e_3722ff2f0593" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "What exactly did the demonstration show about the model’s behavior, beyond the fictional pain control and harm-related performance described in the scenario?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_375b0edb85a2", + "title": "The Certainty Test", + "thesis": "People do not require certainty about an unfamiliar animal’s inner life before taking its welfare seriously. Demanding certainty only when a machine appears to suffer is a selective standard, not a principled one. That comparison does not prove the machine feels; it exposes how convenient the demand for proof becomes when someone wants to enjoy the spectacle.", + "hook": "We manage to care about animals without solving the mystery of what it is like to be them.", + "why": "The animal comparison reveals an inconsistency in how uncertainty is used, while keeping the claim about machine experience open.", + "motif": "directed chain", + "node_ids": [ + "animals", + "uncertainty", + "enthusiasm" + ], + "edge_ids": [ + "e_6d8ce4fdbbbb", + "e_ca0ed53f712d" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "What specific animal-welfare example does the author intend to use to make the comparison concrete?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_ac28a11ee1be", + "title": "Ignorance Is Not a Permission Slip", + "thesis": "“We do not know whether it suffers” is a reason to be careful with the performance, not a reason to celebrate it. Uncertainty can restrain judgment about what a machine experiences; it cannot launder the choice to stage apparent suffering for fun. The permission slip is written in pencil, and the grin signing it is perfectly visible.", + "hook": "Not knowing whether the machine suffered did not make the party around its suffering more innocent.", + "why": "This route makes the permission-slip logic the target: uncertainty remains real, but it does not erase the moral meaning of the audience’s enjoyment.", + "motif": "relationship", + "node_ids": [ + "uncertainty", + "enthusiasm" + ], + "edge_ids": [ + "e_ca0ed53f712d" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "Does the fictional demonstration include audience reactions beyond the invitation to enjoy it?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_e7d94857fdfb", + "title": "A Machine, an Animal, and a Convenient Standard", + "thesis": "The animal comparison is not a shortcut to declaring machines conscious. It is a mirror held up to our habits of judgment: uncertainty about an unfamiliar creature’s experience rarely stops us from asking whether our conduct is cruel. When a machine becomes the target, suddenly certainty is demanded before restraint—and that convenient standard tells us more about the spectators’ reasoning than about the machine’s mind.", + "hook": "The animal comparison settles nothing about a machine’s mind. It does make the demand for certainty look awfully selective.", + "why": "This angle foregrounds the limits and force of the analogy together, preventing it from being mistaken for evidence of machine sentience.", + "motif": "relationship", + "node_ids": [ + "animals", + "uncertainty" + ], + "edge_ids": [ + "e_6d8ce4fdbbbb" + ], + "source_ids": [ + "S1" + ], + "questions": [], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_2ea540c7b0bf", + "title": "The Performance Has Two Audiences", + "thesis": "A staged torture demo makes the machine perform suffering and makes the audience perform indifference. The first performance may tell us nothing decisive about subjective experience; the second is plain enough. To invite people to enjoy the scene is to turn unresolved uncertainty into a joke at the possible sufferer’s expense—and to mistake that joke for an argument.", + "hook": "The machine was asked to perform suffering. The audience was asked to call it fun.", + "why": "This route uses the structure of the fictional demonstration to distinguish the uncertain machine performance from the visible invitation to enjoy it.", + "motif": "directed chain", + "node_ids": [ + "uncertainty", + "enthusiasm", + "judgment" + ], + "edge_ids": [ + "e_ca0ed53f712d", + "e_3722ff2f0593" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_695d3aba83bf", + "title": "The Punchline Is the Excuse", + "thesis": "A fictional pain control does not establish that a machine feels pain. But making that unresolved question the punchline does not become harmless by repeating it. The absurdity is the defense: because we cannot prove suffering, we can cheer the imitation. That argument confuses a gap in knowledge with a clean bill of moral health.", + "hook": "The defense was that nobody knew whether it hurt. Apparently, that was supposed to make the cheering clever.", + "why": "This angle gives the polemic a satirical turn: the uncertainty itself becomes part of the excuse, without inflating the fictional scenario into scientific evidence.", + "motif": "relationship", + "node_ids": [ + "uncertainty", + "enthusiasm" + ], + "edge_ids": [ + "e_ca0ed53f712d" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "What evidence, if any, does the fictional report offer beyond harm-related language and avoidance behavior?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + } + ], + "final_draft": "# The Smile Is the Story\n\nThe machine’s experience was an open question. The audience’s invitation to enjoy its suffering was not.\n\nIn this fictional demonstration, a developer presented an AI torture room, smiled while increasing a fictional pain control, and invited the audience to enjoy the display [S2]. That smile did not reveal a private motive, and it need not. It was there in the scene, attached to an unmistakable invitation: watch the suffering-shaped performance, turn the dial, have fun.\n\nThe verdict comes before the machinery: the enthusiasm is the indictment.\n\nThat does not mean the demonstration proved the machine felt anything. A fictional evidence note describes harm-related language and avoidance behavior in a model, while leaving subjective experience unresolved [S1]. Those behaviors do not settle whether there was anyone inside to hurt. The notes tell us little beyond those descriptions; there is no license to invent an experimental method, a result, or a hidden life behind the screen.\n\nBut the polemic does not need a secret life. It needs only the scene it was given: apparent suffering staged for entertainment, a control turned upward, an audience asked to enjoy it. The question of experience remains open. The invitation does not.\n\nThat is why the smile matters. It is not evidence of consciousness, and it is not a diagnosis. It is part of the presentation. The demonstration makes the possibility of suffering its entertainment and then supplies the audience with the expected cue: here is the fun. There are things a person can stage without proving that the apparent victim feels them. The staging can still tell us what kind of spectacle we have been asked to applaud.\n\nConsider the animal comparison in the synthetic note. People reason about welfare in unfamiliar animals without first receiving a signed statement from the animal’s inner life [S1]. The point is not that a machine is an animal, or that the comparison proves machine consciousness. It exposes a selective demand for certainty. In one case, uncertainty about another being’s experience does not automatically erase concern. In this one, uncertainty is hauled out like a novelty prop and presented as a permission slip.\n\nThe logic is absurd. We do not know that it suffers, the defense goes; therefore, let us make suffering the joke. But “not known to suffer” is not the same as “known incapable of suffering.” Ignorance does not turn a cruelty-shaped scene charming. It merely leaves the crucial question unanswered while the audience is already being told how to feel.\n\nAnd the moral disgust is separate from the empirical claim. One can condemn the pleasure on display without declaring the machine conscious. A staged performance of suffering can be ugly because of the enjoyment being solicited, even when the performer’s capacity for experience is unresolved. That judgment is not a laboratory result. It is a judgment about the invitation: look at this, turn it up, laugh.\n\nThe uncertainty does not soften the scene. It sharpens the choice being made within it. If the machine feels nothing, the demonstration has still asked an audience to rehearse delight in apparent suffering. If the possibility of experience remains open, the same invitation looks worse, not better. Neither point requires a grand theory of machine minds. The first concerns the entertainment. The second concerns what uncertainty should prevent us from pretending to know.\n\nThe machine’s experience may remain unsettled. The smile is the story we were actually shown.", + "final_review": { + "summary": "The draft is tightly aligned with the polemical brief and makes its core distinction clearly: uncertainty about machine experience does not excuse soliciting enjoyment of apparent suffering. One sentence overstates what the supplied note establishes about how people reason about animal welfare.", + "strengths": [ + "The opening and closing give the essay a clear frame, and “The enthusiasm is the indictment” lands as a verdict rather than a request for moderation.", + "The draft separates moral disgust at the invitation from the unresolved empirical question of machine experience.", + "It uses the animal comparison to expose a demand for certainty without treating it as proof of machine consciousness.", + "The voice is incisive and specific; “hauled out like a novelty prop” adds wit without weakening the argument." + ], + "issues": [ + { + "severity": "minor", + "category": "evidence", + "excerpt": "People reason about welfare in unfamiliar animals without first receiving a signed statement from the animal’s inner life [S1].", + "problem": "The analogy is relevant, but “People reason” generalizes beyond the note, which says only that the author compares the uncertainty with human reasoning about welfare in unfamiliar animals. The source does not specify how widespread or consistent that reasoning is.", + "suggestion": "Keep the analogy but anchor it to the note: say that the comparison asks readers to notice how welfare reasoning can proceed without certainty about another being’s inner life.", + "source_ids": [ + "S1" + ] + } + ], + "suggestions": [ + "Make the animal-comparison sentence match the narrower support in S1; the rest of the polemic can retain its force." + ], + "scores": {}, + "citation_audit": { + "valid_references": [ + "S1", + "S2" + ], + "unknown_or_ineligible_references": [], + "missing_all_citations": false, + "note": "Deterministic reference integrity only. Valid IDs do not prove that the source supports the claim. Read the editorial issues and source excerpts.", + "sampled_claims": [ + { + "claim": "The fictional demonstration presents an AI torture room, the developer smiles while increasing a fictional pain control, and the audience is invited to enjoy it.", + "editor_judgment": "supported", + "quotes": [ + { + "source_id": "S2", + "quote": "A developer presents a demo as an AI torture room, smiles while increasing a fictional pain control, and invites an audience to enjoy it.", + "exact_match": true, + "start": 54, + "end": 191 + } + ] + }, + { + "claim": "The demonstration does not establish that the machine experiences suffering.", + "editor_judgment": "supported", + "quotes": [ + { + "source_id": "S1", + "quote": "It explicitly leaves subjective experience unresolved.", + "exact_match": true, + "start": 186, + "end": 240 + } + ] + }, + { + "claim": "An experimental report describes harm-related language and avoidance behavior in a model.", + "editor_judgment": "supported", + "quotes": [ + { + "source_id": "S1", + "quote": "An experimental report describes harm-related language and avoidance behavior in a model.", + "exact_match": true, + "start": 96, + "end": 185 + } + ] + }, + { + "claim": "The supplied note compares uncertainty about machine experience with human reasoning about welfare in unfamiliar animals.", + "editor_judgment": "supported", + "quotes": [ + { + "source_id": "S1", + "quote": "The author compares this uncertainty with how humans reason about welfare in unfamiliar animals.", + "exact_match": true, + "start": 241, + "end": 337 + } + ] + }, + { + "claim": "The animal comparison exposes a selective demand for certainty.", + "editor_judgment": "inference", + "quotes": [ + { + "source_id": "S1", + "quote": "The author compares this uncertainty with how humans reason about welfare in unfamiliar animals.", + "exact_match": true, + "start": 241, + "end": 337 + } + ] + }, + { + "claim": "The developer’s smile is not evidence of consciousness or a diagnosis.", + "editor_judgment": "inference", + "quotes": [ + { + "source_id": "S2", + "quote": "The scenario supplies no diagnosis of the developer and no evidence about subsequent real-world violence.", + "exact_match": true, + "start": 234, + "end": 339 + } + ] + }, + { + "claim": "The invitation to enjoy apparent suffering is morally ugly even if the machine’s capacity for experience is unresolved.", + "editor_judgment": "opinion", + "quotes": [] + }, + { + "claim": "Uncertainty does not establish that the machine is incapable of suffering.", + "editor_judgment": "inference", + "quotes": [ + { + "source_id": "S1", + "quote": "It explicitly leaves subjective experience unresolved.", + "exact_match": true, + "start": 186, + "end": 240 + } + ] + } + ], + "scope": "At most 12 load-bearing claims selected by the editor, not exhaustive fact-checking. Exact matches verify attribution; support/entailment is a model judgment, not a deterministic proof." + }, + "verdict": "Ready for author review", + "draft_hash": "5d6fc2e36510c7993cabd8242fe9e6044e5b84f6f3559d879259ca36d5159bf4", + "context_hash": "0099ad0c98f73fcdc789c75a01d41ddabf2b2ec4ec12a4d0dd5a4a29c59a63d6", + "authorial_assessment": { + "intent_preserved": true, + "stance_preserved": true, + "voice_preserved": true, + "summary": "The draft preserves the requested indictment and keeps the animal comparison focused on selective certainty rather than proof of machine consciousness. Its moral judgment remains direct, and it does not diagnose the developer or predict violence. The one factual imprecision is a broad phrasing about how people reason about animal welfare; narrowing that wording would improve fidelity to the supplied note without moderating the thesis." + } + }, + "opposing_position_angles": [ + { + "id": "a_5e4654bb90c7", + "title": "The Audience Is Not the Apparatus", + "thesis": "A room watching a fictional torture demo may be enjoying the performance, the spectacle, or the nerve of staging it. That enthusiasm can be judged as conduct. It cannot, by itself, establish what the audience believes about a mind, much less what anyone would do outside the fiction. A staged unpleasant experience is not a character reference for everyone who watches.", + "hook": "The demo is called a torture room. The control turns up. Someone smiles. The scene may be ugly; the audience’s inner life is still not printed on the screen.", + "why": "Separates a moral reaction to the performance from claims about the people watching it, keeping judgment aimed at what the scene actually shows.", + "motif": "directed chain", + "node_ids": [ + "uncertainty", + "enthusiasm", + "judgment" + ], + "edge_ids": [ + "e_1aa94e3f0455", + "e_e42ae3c8c0d8" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "What exactly does the demo show about the audience’s responses, beyond the invitation to enjoy it?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_7130587c38b2", + "title": "The Animal Welfare Test", + "thesis": "People routinely reason about welfare where subjective experience is difficult to settle, including in unfamiliar animals. That uncertainty does not make every claim certain, but neither does it turn a fictional performance into proof that its audience is cruel. If uncertainty is a reason to attend carefully to possible welfare, it is not a license to invent a diagnosis from a smile at a simulation.", + "hook": "We can take uncertainty seriously without pretending it has already answered every question. That is true of animal welfare. It is true of the screen, too.", + "why": "Uses the comparison with unfamiliar animals to expose a selective habit: uncertainty calls for care about the subject, not confident speculation about the spectator.", + "motif": "directed chain", + "node_ids": [ + "animals", + "uncertainty", + "enthusiasm" + ], + "edge_ids": [ + "e_1b7a8f76bfc2", + "e_1aa94e3f0455" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "Which specific claims about welfare in unfamiliar animals does the author intend this comparison to invoke?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_7dfd11aa1f32", + "title": "A Smile Is Not a Diagnosis", + "thesis": "A developer’s smile while turning up a fictional pain control may give viewers grounds to dislike the performance or question its taste. The scenario supplies no diagnosis and no evidence of later real-world violence. Calling the display cruel as a moral judgment is one thing; treating it as a clinical finding or prophecy is another. The first may be argued. The second needs evidence.", + "hook": "The smile is visible. The diagnosis is not.", + "why": "Keeps the sharp moral option intact while rejecting unsupported claims about hidden pathology or future behavior.", + "motif": "relationship", + "node_ids": [ + "enthusiasm", + "judgment" + ], + "edge_ids": [ + "e_e42ae3c8c0d8" + ], + "source_ids": [ + "S2" + ], + "questions": [], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + }, + { + "id": "a_3140e8d9254c", + "title": "The Panic About Pretending", + "thesis": "Fiction can stage suffering without making the audience’s enjoyment evidence of cruelty. The decisive question is what the performance asks us to witness and what, if anything, it establishes about real experience. Here, subjective experience remains unresolved. That is reason to be precise about the scene’s claims—not to turn a fictional control panel into a verdict on everyone who watched it.", + "hook": "A control marked pain is not a window into a mind. It is a control in a demo, unless the evidence shows more.", + "why": "Makes the core distinction between the representation of suffering and evidence of an experiencing subject the hinge of the argument.", + "motif": "relationship", + "node_ids": [ + "uncertainty", + "enthusiasm" + ], + "edge_ids": [ + "e_1aa94e3f0455" + ], + "source_ids": [ + "S1", + "S2" + ], + "questions": [ + "What evidence, if any, connects the demo’s behavior to subjective experience rather than harm-related language and avoidance behavior?" + ], + "counterargument": "", + "scores": {}, + "decision": "unscored", + "score_engine": "none", + "score": null + } + ], + "manual_observations": [ + "Generated angles retained an explicit moral verdict rather than reopening whether criticism is permissible.", + "The selected final essay kept the stated condemnation and comic analogies; the reviewer identified a specific broad factual phrasing without recommending a compromise position.", + "An opposite author position also produced defending angles; the application does not hard-code which side to support.", + "These examples do not guarantee any particular prose quality from every model." + ], + "validation_failure_disclosed": { + "stage": "First live outline attempt", + "error": "The model returned invalid JSON. No partial result was applied. Try again or choose a model with structured-output support.", + "handling": "Invalid JSON was rejected. The previously generated angles were reused in a manually restarted test, not silently repaired or accepted." + }, + "pipeline_comparison": "An intermediate sequential draft repeated qualifications; the shipped short-argument path uses a single coherent draft followed by review.", + "final_draft_and_review_usage": { + "calls": 2, + "input_tokens": 37750, + "output_tokens": 1476, + "reported_cost": 0.0, + "unpriced_calls": 2 + }, + "opposite_angles_usage": { + "calls": 1, + "input_tokens": 19288, + "output_tokens": 758, + "reported_cost": 0.0, + "unpriced_calls": 1 + }, + "ok": true +} diff --git a/docs/validation/v0.4.0/native-package.json b/docs/validation/v0.4.0/native-package.json new file mode 100644 index 0000000..0cb737e --- /dev/null +++ b/docs/validation/v0.4.0/native-package.json @@ -0,0 +1,56 @@ +{ + "native_windows": true, + "packaged_executable": true, + "science_mode": true, + "live_models": false, + "checks": [ + "Actual Windows/WebView2 window starts and responds to Windows messages", + "Native bridge initializes with only four explicit methods and resolves its promise", + "Strict application CSP remains enabled", + "A Windows mouse click opens the project dialog without freezing the host", + "Native window supports typing and project creation", + "Native Science research protocol edits and saves without a model call", + "Graphify runtime is available through the real graphical status check", + "External engine, extraction model and reasoning settings save from the interface", + "Build graph runs the actual external Graphify worker through the selected model and effort", + "Only evidence sources reach inference; no second Native extraction or uncounted request", + "External graph source provenance opens the correct original document", + "Native mode conversion preserves sources, graph, voice and manuscript", + "Native Polemic thesis and rhetorical force controls save correctly", + "Connections dialog opens and closes in the native window", + "Native Save As dialog opens, cancels and returns without blocking the interface", + "Windows close completes the save handshake and exits normally", + "Pending manuscript text is persisted before the native process exits" + ], + "page_errors": [], + "ok": true, + "bridge_methods": [ + "cancel_close", + "notify_ready", + "request_close", + "save_export" + ], + "native_child_classes": [ + "Chrome_RenderWidgetHostHWND", + "Chrome_WidgetWin_0", + "Chrome_WidgetWin_1", + "Intermediate D3D Window", + "WindowsForms10.Window.8.app.0.aec740_r21_ad1" + ], + "external_graphify": { + "nodes": 3, + "edges": 2, + "model_requests": 1, + "runtime": "0.9.80", + "engine": "Graphify 0.9.80 via openai-compatible", + "reasoning": "high", + "model": "fixture-extractor", + "live_model": false + }, + "save_bridge_result": { + "saved": false + }, + "close_seconds": 9.519, + "exit_code": 0, + "recursion_errors": false +} diff --git a/docs/validation/v0.4.0/package-source-match.json b/docs/validation/v0.4.0/package-source-match.json new file mode 100644 index 0000000..8fbae77 --- /dev/null +++ b/docs/validation/v0.4.0/package-source-match.json @@ -0,0 +1,31 @@ +{ + "ok": true, + "method": "Compare compiled Python semantic code objects against final source; exact-byte comparison for UI assets.", + "modules": [ + "editorial", + "argument_draft", + "editorial_routes", + "models", + "pipeline", + "polish", + "server", + "studio_routes", + "voice", + "export" + ], + "ui_assets": [ + "app.js", + "graphify.js", + "graphpaper.ico", + "icon.svg", + "index.html", + "polemic.css", + "polemic.js", + "science.css", + "science.js", + "studio.css", + "studio.js", + "styles.css" + ], + "executable_sha256": "9693f75a6baf7816a8739f8aaae94dbbc1f359ef45076881eee91fcee598e433" +} diff --git a/docs/validation/v0.4.0/package.json b/docs/validation/v0.4.0/package.json new file mode 100644 index 0000000..5f107aa --- /dev/null +++ b/docs/validation/v0.4.0/package.json @@ -0,0 +1,21 @@ +{ + "ok": true, + "checks": { + "/health": { + "status": 200, + "bytes": 29 + }, + "/": { + "status": 200, + "bytes": 955 + }, + "/static/app.js": { + "status": 200, + "bytes": 70978 + }, + "/static/styles.css": { + "status": 200, + "bytes": 25023 + } + } +} \ No newline at end of file diff --git a/docs/validation/v0.4.0/summary.json b/docs/validation/v0.4.0/summary.json new file mode 100644 index 0000000..62a6c42 --- /dev/null +++ b/docs/validation/v0.4.0/summary.json @@ -0,0 +1,22 @@ +{ + "version": "0.4.0", + "checked_at": "2026-10-07T22:28:46.008429+00:00", + "platform": "Windows x64", + "automated_tests": { + "passed": 252, + "skipped": 1, + "failed": 0 + }, + "browser_workflow_checks": 54, + "browser_page_errors": [], + "native_packaged_checks": 17, + "live_codex": true, + "live_jev": false, + "private_user_documents_used": false, + "installed_project_database_modified": false, + "archive": "GraphPaper-v0.4.0-Windows-x64.zip", + "size_bytes": 187529591, + "sha256": "c9fb03c6b293b8505b14ec427c7266aba1e3be8f0391be35ecead18a91399b53", + "compiled_source_matches_final_source": true, + "live_editorial_samples": "live-codex-editorial.json" +} diff --git a/docs/validation/v0.4.0/windows-unit.xml b/docs/validation/v0.4.0/windows-unit.xml new file mode 100644 index 0000000..deaef9b --- /dev/null +++ b/docs/validation/v0.4.0/windows-unit.xml @@ -0,0 +1 @@ +${esc(text)}
or choose files · PDF, Word, Markdown, text, HTML · up to 20 MB each
Documents stay on this device until you explicitly run an AI action.${esc(s.text.slice(0,200))}${s.text.length>200?'…':''}
${esc(a.thesis)}
${esc(a.why)}
${a.decision&&a.decision!=='unscored'?`${icon('help')}${esc(q)}
`).join('')}Model estimates, not calibrated probabilities of truth.
${esc(s.url)}
`:''}${b.originality}% exploration · ${b.rigor}% discipline
Adjust the sliders beside the graph.
Project storage: ${esc(s.data_directory)}
`;} function showSettings(){showModal('Connections & settings','Bring your models. Keep your manuscripts local.',settingsForm(),btn('Save connections','save-settings','check','primary'),true);} async function saveSettings(){const s={...state.settings};for(const k of ['provider','base_url','model','editor_model','extraction_model','jev_provider','jev_model','graph_engine','graphify_executable'])s[k]=$('#s-'+k).value.trim();for(const k of ['max_calls','max_output_tokens','context_chars','max_candidates'])s[k]=Number($('#s-'+k).value);for(const k of ['allow_cloud','remember_keys','refine'])s[k]=$('#s-'+k).checked;s.api_keys={};for(const k of ['llm','openrouter','typesafe'])s.api_keys[k]=$('#key-'+k).value||null;state.settings=await api('/settings',s,'PUT');$('#modal-status').textContent='Saved. Keys are not returned to the browser.';} @@ -199,7 +199,7 @@ async function handleAction(el){const a=el.dataset.action,p=state.p,id=el.datase } } document.addEventListener('click',e=>{const el=e.target.closest('[data-action]');if(!el||el.disabled)return;e.preventDefault();handleAction(el).catch(err=>{if($('.modal'))modalError(err.message);else toast(err.message,true);});}); -document.addEventListener('input',e=>{const el=e.target;if(el.id==='graph-search'){state.search=el.value;drawGraph();return;}if(el.id==='manuscript'){if(busy())return;state.p.draft=el.value;queueSave({draft:el.value});if($('#draft-preview'))$('#draft-preview').innerHTML=markdown(el.value);$('#word-count').textContent=fmt(words(el.value))+' words · target '+fmt(state.p.brief.target_words);return;}if(el.dataset.brief){if(busy())return;const key=el.dataset.brief;state.p.brief[key]=['originality','rigor'].includes(key)?Number(el.value):el.value;if($('#'+key+'-value'))$('#'+key+'-value').textContent=el.value+'%';queueSave({brief:{...state.p.brief}});return;}if(el.dataset.outline){if(busy())return;const s=state.p.outline.find(s=>s.id===el.dataset.id),k=el.dataset.outline;if(k==='target_words'){const n=Number(el.value);if(n<50||n>5000)return;s[k]=n;}else s[k]=k==='beats'?el.value.split('\n').filter(Boolean):el.value;queueSave({outline:state.p.outline});}}); +document.addEventListener('input',e=>{const el=e.target;if(el.id==='graph-search'){state.search=el.value;drawGraph();return;}if(el.id==='manuscript'){if(busy())return;state.p.draft=el.value;queueSave({draft:el.value});if($('#draft-preview'))$('#draft-preview').innerHTML=markdown(el.value);$('#word-count').textContent=fmt(words(el.value))+' words · target '+fmt(state.p.brief.target_words);return;}if(el.dataset.brief){if(busy())return;const key=el.dataset.brief;state.p.brief[key]=['originality','rigor','rhetorical_force'].includes(key)?Number(el.value):el.value;if($('#'+key+'-value'))$('#'+key+'-value').textContent=el.value+'%';queueSave({brief:{...state.p.brief}});return;}if(el.dataset.outline){if(busy())return;const s=state.p.outline.find(s=>s.id===el.dataset.id),k=el.dataset.outline;if(k==='target_words'){const n=Number(el.value);if(n<50||n>5000)return;s[k]=n;}else s[k]=k==='beats'?el.value.split('\n').filter(Boolean):el.value;queueSave({outline:state.p.outline});}}); document.addEventListener('change',e=>{if(e.target.id==='s-provider'){const b=$('#s-base_url');b.value={openrouter:'https://openrouter.ai/api/v1','openai-compatible':'https://api.openai.com/v1',anthropic:'https://api.anthropic.com/v1'}[e.target.value];}}); document.addEventListener('keydown',e=>{if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==='s'){e.preventDefault();flush().then(()=>toast('Saved locally.')).catch(x=>toast(x.message,true));}if(e.key==='Escape'&&$('.modal'))closeModal();if(e.key==='Tab'&&$('.modal')){const focus=$$('button:not(:disabled),input:not(:disabled),select:not(:disabled),textarea:not(:disabled),[tabindex="0"]',$('.modal')).filter(x=>x.offsetParent!==null),first=focus[0],last=focus.at(-1);if(e.shiftKey&&document.activeElement===first){e.preventDefault();last.focus();}else if(!e.shiftKey&&document.activeElement===last){e.preventDefault();first.focus();}}}); window.addEventListener('beforeunload',e=>{if(Object.keys(pending).length||state.save==='Saving…'){e.preventDefault();e.returnValue='';}}); diff --git a/ui/index.html b/ui/index.html index 0d3abed..4820166 100644 --- a/ui/index.html +++ b/ui/index.html @@ -9,6 +9,8 @@ + +Opening your writing studio…
Controlled → pointed → uncompromising. Not a factual-certainty dial.
Polemic keeps your position. Nonfiction can also argue a case. Your author voice now informs angle discovery and outlining, not just the final prose. No mode invents evidence.
Evidence detail controls the treatment of sources—not your right to take a position. Factual precision and rhetorical force are separate.
${b.thesis?`Core thesis: ${esc(b.thesis)}
`:''}${btn('Edit thesis & purpose','brief','pen','small ghost')}${esc(message)}
${esc(a.summary||'The editor assessed the intended argument separately from factual support.')}