diff --git a/docs/REVIEWER_TRUST_MAP.md b/docs/REVIEWER_TRUST_MAP.md index 81573189..3340f967 100644 --- a/docs/REVIEWER_TRUST_MAP.md +++ b/docs/REVIEWER_TRUST_MAP.md @@ -28,7 +28,7 @@ Recommended first paths: - I want the shortest public-facing overview: start with [`EXECUTIVE_SUMMARY.md`](EXECUTIVE_SUMMARY.md), then use [`PRODUCTION_READINESS_SUMMARY.md`](PRODUCTION_READINESS_SUMMARY.md) for the production-candidate snapshot, [`SRE_DEMO_HIGHLIGHTS.md`](SRE_DEMO_HIGHLIGHTS.md) for the product-value/guardrail one-pager, and [`DEMO_WALKTHROUGH.md`](DEMO_WALKTHROUGH.md) for a local demo script. - I want to verify tests and coverage: start with [`TESTING_COVERAGE.md`](TESTING_COVERAGE.md), then inspect the `jacoco-coverage-report` workflow artifact and CI skipped-test log output. - I want to verify real HTTP proxy behavior: start with [`REVERSE_PROXY_MODE.md`](REVERSE_PROXY_MODE.md), [`REVERSE_PROXY_HEALTH_AND_METRICS.md`](REVERSE_PROXY_HEALTH_AND_METRICS.md), [`REVERSE_PROXY_RESILIENCE.md`](REVERSE_PROXY_RESILIENCE.md), [`PROXY_OPERATOR_STATUS_UI.md`](PROXY_OPERATOR_STATUS_UI.md), the source-visible `LocalOnlyRealBackendProxyValidationTest`, and the reviewer export from `LocalProxyEvidenceExportTest` under `target/proxy-evidence/local-proxy-evidence.md`. -- I want to inspect request-level routing decisions: open `/routing-demo.html` and use the Reviewer Workflow Checklist, Evidence Associations, Association Legend, Routing Proof Summary, Scenario Comparison, Reviewer Confidence Signals, and Evidence Navigation reviewer path for selected scenario-to-decision mapping, selected strategy/backend, scenario-to-scenario what-changed notes, visible input signal deltas, unhealthy-candidate degradation/recovery notes, local verification commands, routing-to-evidence dashboard links, copyable association summary, an end-to-end reviewer walkthrough, and explicit not-proven limits. +- I want to inspect request-level routing decisions: open `/routing-demo.html` and use the Reviewer Workflow Checklist, How This Proof Works, Evidence Associations, Association Legend, Routing Proof Summary, Scenario Comparison, Reviewer Confidence Signals, and Evidence Navigation reviewer path for selected scenario-to-decision mapping, selected strategy/backend, scenario-to-scenario what-changed notes, visible input signal deltas, unhealthy-candidate degradation/recovery notes, local verification commands, routing-to-evidence dashboard links, copyable how-to reviewer explanation, copyable association summary, an end-to-end reviewer walkthrough, and explicit not-proven limits. - I want to run local proxy demos: start with [`PROXY_DEMO_STACK.md`](PROXY_DEMO_STACK.md), [`PROXY_DEMO_FIXTURE_LAUNCHER.md`](PROXY_DEMO_FIXTURE_LAUNCHER.md), and [`PROXY_STRATEGY_DEMO_LAB.md`](PROXY_STRATEGY_DEMO_LAB.md). - I want to adapt proxy mode to local/private backends: start with [`REAL_BACKEND_PROXY_EXAMPLES.md`](REAL_BACKEND_PROXY_EXAMPLES.md). - I want to choose the right run profile: start with [`OPERATOR_RUN_PROFILES.md`](OPERATOR_RUN_PROFILES.md) for local demo, packaged jar, prod API-key, cloud-sandbox API-key, OAuth2, proxy-loopback, and container recipes. @@ -83,6 +83,10 @@ Use the Evidence Associations panel on `/routing-demo.html` to connect selected The Association Legend keeps the proof language readable: scenario = demo input state, strategy = selected routing method, backend/server = selected local candidate from the sample response, signals = local/demo metrics used for explanation, and evidence pages = reviewer navigation aids, not production certification. This association map does not prove production traffic, live cloud behavior, real tenant behavior, registry publication, container signing, or production certification. +### Cockpit How-Question Guide + +Use the How This Proof Works panel on `/routing-demo.html` when a reviewer asks how to interpret the selected decision, reproduce the proof, read edge cases, understand strategy choice, or follow evidence support. The copyable how-to reviewer explanation is browser-local text assembled from visible page guidance and local comparison state only: no upload/share endpoint, no server-side export/PDF/ZIP generation, no external calls, no telemetry, no production traffic proof, no live cloud proof, no real tenant proof, no registry publication proof, no container signing proof, no GitHub settings mutation proof, and no production certification claim. + ## Reviewer Demo Path Use this path when a reviewer wants to understand the project and verify the current evidence story in about five minutes without enabling live private-network behavior. @@ -95,7 +99,7 @@ What can be proven quickly: 2. Operator evidence dashboard: open `http://localhost:8080/operator-evidence-dashboard.html` for local/CI evidence locations, smoke output paths, dry-run artifact metadata, and the local-only `GET /api/enterprise-lab/operator-evidence-summary` response. 3. Evidence timeline: open `http://localhost:8080/evidence-timeline.html` for local/CI evidence stages, generated evidence locations, the dry-run artifact name, and a reusable run template. 4. Evidence export packet: open `http://localhost:8080/evidence-export-packet.html` for the reviewer handoff checklist, packet template, reviewer packet share checklist, browser-local Markdown/JSON packet downloads, browser print/save-as-PDF styling, dashboard links, CI artifact name, not-proven boundaries, and the local-only `GET /api/enterprise-lab/evidence-export-packet` response. The downloads, print flow, and share checklist are generated in the browser and do not send, upload, or create server-side files, PDFs, or share artifacts. -5. Local routing/cockpit behavior: open `http://localhost:8080/routing-demo.html` for the Reviewer Workflow Checklist, Evidence Associations, Association Legend, Routing Proof Summary, Scenario Comparison, Reviewer Confidence Signals, Evidence Navigation reviewer path, selected scenario-to-decision mapping, selected strategy/backend, scenario-to-scenario what-changed notes, visible input signal deltas, degradation/recovery notes, local verification commands, routing-to-evidence dashboard links, copyable evidence association summary, copyable end-to-end reviewer walkthrough, and explicit not-proven boundaries; then open `http://localhost:8080/` and `http://localhost:8080/load-balancing-cockpit.html`. +5. Local routing/cockpit behavior: open `http://localhost:8080/routing-demo.html` for the Reviewer Workflow Checklist, How This Proof Works, Evidence Associations, Association Legend, Routing Proof Summary, Scenario Comparison, Reviewer Confidence Signals, Evidence Navigation reviewer path, selected scenario-to-decision mapping, selected strategy/backend, scenario-to-scenario what-changed notes, visible input signal deltas, degradation/recovery notes, local verification commands, routing-to-evidence dashboard links, copyable how-to reviewer explanation, copyable evidence association summary, copyable end-to-end reviewer walkthrough, and explicit not-proven boundaries; then open `http://localhost:8080/` and `http://localhost:8080/load-balancing-cockpit.html`. 6. Local proxy forwarding evidence: run `mvn -Dtest=LocalProxyEvidenceExportTest test`, then inspect `target/proxy-evidence/local-proxy-evidence.md` and `target/proxy-evidence/local-proxy-evidence.json`. 7. Private-network profile dry-run evidence: run `mvn -Dtest=PrivateNetworkProxyDryRunEvidenceTest test`, then inspect `target/proxy-evidence/private-network-validation-dry-run.md` and `target/proxy-evidence/private-network-validation-dry-run.json`. 8. Private-network live loopback proof: run `mvn -Dtest=PrivateNetworkLiveValidationExecutorTest test`, then inspect `target/proxy-evidence/private-network-live-loopback-validation.md` and `target/proxy-evidence/private-network-live-loopback-validation.json`. @@ -135,6 +139,7 @@ Safety boundaries preserved by this path: | Where is the reviewer evidence export packet? | Static browser dashboard and local summary API | `/evidence-export-packet.html`, `GET /api/enterprise-lab/evidence-export-packet`, `src/main/resources/static/evidence-export-packet.html` | Reviewer handoff checklist, reviewer packet share checklist, browser-local Markdown/JSON downloads, browser print/save-as-PDF styling, copyable packet template, evidence paths, dashboard/API links, CI artifact metadata, not-proven boundaries, residual risks, and follow-up gates | Reviewers can assemble, download, print, or share-check a consistent human-readable handoff packet from existing local/CI evidence without server-side file creation, uploads, releases, signatures, registry publications, or production-readiness claims | Production certification, registry publication, container signing, live cloud validation, real tenant proof, server-side export/share artifact creation, or GitHub settings mutation | | How do routing decisions connect to reviewer evidence pages? | Static browser routing demo association panels | `/routing-demo.html`, `RoutingDecisionDemoTest`, `src/main/resources/static/routing-demo.html` | Evidence Associations, Association Legend, copyable evidence association summary, selected scenario-to-decision mapping, selected strategy/backend mapping, key input signal mapping, scenario comparison delta, evidence page links, export packet handoff link, and local/demo-only not-proven boundaries | Reviewers can trace how a synthetic scenario, routing decision, selected backend, visible signals, scenario delta, evidence pages, timeline, and handoff packet relate without adding server-side exports or external calls | Production traffic proof, live cloud proof, real tenant proof, production certification, registry publication, container signing, upload/share endpoint behavior, or server-side export/PDF/ZIP generation | | How should a reviewer walk the routing cockpit end-to-end? | Static browser routing demo workflow panels | `/routing-demo.html`, `RoutingDecisionDemoTest`, `src/main/resources/static/routing-demo.html` | Reviewer Workflow Checklist, Reviewer Confidence Signals, copyable end-to-end reviewer walkthrough, Evidence Navigation links, and local/demo-only not-proven boundaries | Reviewers can follow a repeatable local sequence from sample scenario to routing comparison, proof summary, scenario deltas, evidence dashboards, timeline, and evidence export packet without leaving static/browser-local surfaces | Production deployment certification, live cloud validation, real tenant traffic proof, production SLA/SLO evidence, upload/share endpoint behavior, server-side export/PDF/ZIP generation, registry publication, or container signing | +| How should reviewers interpret routing proof details and edge cases? | Static browser routing demo how-question guide | `/routing-demo.html`, `RoutingDecisionDemoTest`, `src/main/resources/static/routing-demo.html` | How This Proof Works, How to Interpret This Decision, How to Reproduce This Proof, How to Read Edge Cases, How Strategy Choice Matters, How Evidence Supports the Decision, copyable how-to reviewer explanation, and local/demo-only not-proven boundaries | Reviewers can answer how the selected backend was chosen, how strategy and input signals influenced the proof, how edge cases should be read, how to reproduce the local proof, and how evidence pages support the decision without leaving static/browser-local surfaces | Production traffic proof, live cloud proof, real tenant proof, production certification, registry publication, container signing, GitHub settings mutation proof, upload/share endpoint behavior, or server-side export/PDF/ZIP generation | | How do routing proof scenarios compare? | Static browser routing demo and local compare API | `/routing-demo.html`, `RoutingDecisionDemoTest`, `src/main/resources/static/routing-demo.html` | Routing Proof Summary, Scenario Comparison, Evidence Associations, Evidence Navigation reviewer path, previous/current scenario names, selected strategy/backend delta, input signal deltas, degradation/recovery notes, routing-to-evidence dashboard links, copyable local reviewer summary, copyable evidence association summary, and copyable end-to-end reviewer walkthrough | Reviewers can compare the packaged normal-load baseline against edited local demo payloads using same-origin local API responses, browser-local copy text, and static links to the reviewer/operator/timeline/export packet pages | Production deployment certification, live cloud validation, real tenant traffic proof, production SLA/SLO evidence, server-side export/share artifact creation, registry publication, or container signing | | What governance changes are prepared but manual? | Repo-side governance hardening packet | [`MANUAL_GITHUB_GOVERNANCE_HARDENING.md`](MANUAL_GITHUB_GOVERNANCE_HARDENING.md), [`../.github/CODEOWNERS`](../.github/CODEOWNERS) | CODEOWNERS coverage, current observed ruleset state, manual settings checklist, stale-review recommendation, and evidence expectations | Reviewers can see ownership and target governance decisions without assuming GitHub settings were changed | Applied ruleset mutation, required review enforcement, branch-protection mutation, or production governance certification | | Is this enterprise-ready? | Current enterprise-readiness audit | [`ENTERPRISE_READINESS_AUDIT.md`](ENTERPRISE_READINESS_AUDIT.md) | Current `main`/`v2.5.0` audit, GitHub ruleset and alert snapshot, Enterprise Lab transition decision, remaining gaps | Reviewers can distinguish Enterprise Lab readiness from production enterprise readiness | Production gateway certification, deployment approval, real IdP tenant proof, live cloud validation, or container signing | diff --git a/src/main/resources/static/routing-demo.html b/src/main/resources/static/routing-demo.html index 398d969c..ae3298cd 100644 --- a/src/main/resources/static/routing-demo.html +++ b/src/main/resources/static/routing-demo.html @@ -481,44 +481,89 @@

Copyable evidence association summary

How This Proof Works

- Reviewer/operator answers for common routing-proof questions. +
+ +
-
+

Reviewer/operator answers for interpreting the local routing proof without turning demo evidence into a production claim.

+

How to Interpret This Decision

+
+
+ How was the selected backend chosen? +

The first returned comparison result is the primary local decision. It names the selected backend/server, includes returned reason text, and should be read against the visible candidate list.

+
- How the selected strategy affects the selected backend -

The first returned strategy is the primary local comparison result; its routing rule ranks the visible candidate servers and returns the selected backend/server plus reason text.

+ How did the selected strategy influence the decision? +

The selected strategy applies its scoring or selection behavior to the same visible candidates; compare the strategy name, selected backend/server, and reason text before treating two results as equivalent.

- How input signals influence the routing proof + How did input signals affect the proof?

Health, in-flight load, configured weight/capacity, p95 latency, error rate, queue depth, and network-awareness fields are summarized from the visible payload so reviewers can inspect why a backend was preferred or avoided.

- How scenario comparison deltas are summarized -

Deltas are browser-local summaries comparing packaged baseline metrics against the current editor payload: candidate count, healthy/unhealthy count, total in-flight load, max p95 latency, max error rate, and queue depth.

+ How should reviewers interpret confidence/limits? +

Confidence means the browser can repeat the same local sample flow, show deterministic visible inputs, and copy the same reviewer note; it does not mean the result is approved for production use.

- How degradation, unhealthy, and recovery states are represented -

Unhealthy backends are counted from healthy=false; all-unhealthy payloads are called out as a degradation boundary, while fewer unhealthy backends than the baseline are described as recovery.

+ How does this differ from production proof? +

Local/demo proof uses synthetic payloads, same-origin local API responses, and browser-local notes; it does not prove production traffic, live cloud behavior, real tenant behavior, registry publication, container signing, or production certification.

+
+

How Strategy Choice Matters

+
- How to reproduce the same proof locally -

Run mvn spring-boot:run, open this page, load the sample scenario, run Compare strategies, and compare the visible response with the copyable curl and proof notes.

+ Strategy affects scoring/selection behavior +

Each strategy can rank the same candidates differently, so reviewers should compare the selected strategy, selected backend/server, and returned reason before drawing conclusions.

- How evidence pages relate to the proof -

The routing page explains the request-level decision; reviewer, operator, timeline, and export packet pages provide navigation, evidence locations, history context, and handoff text.

+ Strategy changed but backend stayed the same +

The selected backend can remain unchanged even if the strategy changes when multiple strategies still prefer the same local candidate.

- How the copied association summary should be used -

Use the copied association summary as a reviewer note that points to visible local proof and evidence pages; it is not an audit artifact created by the server.

+ Backend changed but strategy stayed the same +

The selected backend can change under the same strategy when visible signals such as health, in-flight load, latency, error rate, queue depth, or capacity shift.

- How local/demo proof differs from production proof -

Local/demo proof uses synthetic payloads, same-origin local API responses, and browser-local notes; it does not prove production traffic, live cloud behavior, real tenant behavior, registry publication, container signing, or production certification.

+ Explanatory/demo evidence only +

Cockpit output explains local sample behavior; it is not production certification, SLA/SLO proof, real-tenant proof, live-cloud proof, or registry/signing proof.

-

Edge-case reading guide

+

How to Reproduce This Proof

+
    +
  1. Run the app locally and open /routing-demo.html.
  2. +
  3. Load a sample scenario so the request editor uses deterministic synthetic input.
  4. +
  5. Run routing comparison to call the same-origin local /api/routing/compare endpoint.
  6. +
  7. Review selected strategy/backend in Routing Proof Summary.
  8. +
  9. Compare scenario deltas for strategy, backend/server, input signal, and degradation/recovery changes.
  10. +
  11. Copy proof, walkthrough, association, or how-to summaries from visible browser text.
  12. +
  13. Follow evidence pages for reviewer dashboard, operator evidence, timeline/history, and export packet handoff.
  14. +
  15. Use browser-local export/copy/print packet actions from /evidence-export-packet.html.
  16. +
+

How Evidence Supports the Decision

+
+
+ Routing Proof Summary is the immediate decision view +

It shows the selected strategy, selected backend/server, visible input signals, and local/demo boundary for the current comparison.

+
+
+ Scenario Comparison shows change over time/input states +

It summarizes previous/current scenario names, strategy/backend deltas, signal deltas, and degradation or recovery notes from visible local inputs.

+
+
+ Scenario comparison deltas are browser-local summaries +

Deltas compare packaged baseline metrics against the current editor payload: candidate count, healthy/unhealthy count, total in-flight load, max p95 latency, max error rate, and queue depth.

+
+
+ Evidence Navigation links related reviewer pages +

Reviewer, operator, timeline, and export packet pages are static navigation aids for following the proof path; they are not live telemetry or certification pages.

+
+
+ Export packet is a local reviewer handoff +

The packet page supports browser-local copy, download, and print review; it is not a server-generated certification artifact.

+
+
+

How to Read Edge Cases

  • No previous scenario has been captured yet; the packaged normal-load baseline remains the static reference.
  • Same scenario run twice or unchanged from baseline: strategy order and input signal totals should read as unchanged.
  • @@ -530,7 +575,15 @@

    Edge-case reading guide

  • API error or unavailable local server: Local API response unavailable; static guidance remains available.
  • Copy-to-clipboard failure fallback: Copy failed; select the visible text and copy manually.
  • Static page loaded without prior interaction: static guidance and evidence links remain available before running a scenario.
  • +
  • Evidence links before scenario execution: Evidence links are available even before running a scenario.
+

+ Copy boundary: the how-to reviewer explanation is assembled in the browser from visible static guidance + and local comparison state only; no upload/share endpoint, no server-side export/PDF/ZIP generation, + no external calls, and no telemetry. +

+

Copyable how-to reviewer explanation

+
Static guidance remains available before running a scenario. Load the sample scenario and run Compare strategies to generate the how-to reviewer explanation.
@@ -920,7 +973,8 @@

6. Safety limitations

proofSummary: document.getElementById("proof-summary-output"), scenarioComparison: document.getElementById("scenario-comparison-output"), reviewerWalkthrough: document.getElementById("reviewer-walkthrough-output"), - evidenceAssociation: document.getElementById("evidence-association-output") + evidenceAssociation: document.getElementById("evidence-association-output"), + howToReviewer: document.getElementById("how-to-reviewer-output") }; const proofFields = { strategy: document.getElementById("proof-strategy"), @@ -1163,6 +1217,7 @@

6. Safety limitations

renderScenarioComparison(); renderEvidenceAssociations(); renderReviewerWalkthrough(); + renderHowToReviewerExplanation(); } function currentRequestPayload() { @@ -1580,6 +1635,80 @@

6. Safety limitations

].join("\n"); } + function renderHowToReviewerExplanation() { + const results = lastRoutingBody && Array.isArray(lastRoutingBody.results) + ? lastRoutingBody.results + : []; + const primary = results.length > 0 ? results[0] : null; + const selectedStrategy = primary && primary.strategyId ? primary.strategyId : "not run"; + const selectedBackend = primary && primary.chosenServerId ? primary.chosenServerId : "not run"; + const reason = primary && primary.reason + ? primary.reason + : (lastRoutingError || "No routing reason is available until Compare strategies runs. Static guidance remains available before interaction."); + const proofSignals = proofFields.signals.textContent || "Run Compare strategies to summarize visible request fields."; + const comparisonSignals = scenarioFields.signals.textContent || "Run Compare strategies to compare input signal deltas."; + const degradation = scenarioFields.degradation.textContent || "Run Compare strategies to compare degradation or recovery notes."; + + outputs.howToReviewer.textContent = [ + "# Cockpit How-To Reviewer Explanation", + "", + "howQuestionInventory:", + "- already answered: selected strategy/backend, input signals, scenario deltas, degradation/recovery notes, evidence path, copy boundaries, and local/demo limits", + "- clarified in this panel: interpretation sequence, reproduction steps, edge-case reading, strategy-choice effects, and evidence support boundaries", + "", + "howToInterpretThisDecision:", + "- selectedBackendChosen: " + selectedBackend + " from the primary local comparison result", + "- selectedStrategyInfluence: " + selectedStrategy + " applies its scoring or selection behavior to visible local candidates", + "- returnedReason: " + reason, + "- inputSignalsAffectingProof: " + proofSignals, + "- confidenceLimits: local repeatability and deterministic visible inputs only; not production certification", + "- localVsProductionProof: synthetic payloads, same-origin local API responses, and browser-local notes do not prove production traffic, live cloud behavior, real tenant behavior, registry publication, container signing, GitHub settings mutation, or production certification", + "", + "howToReproduceThisProof:", + "1. run the app locally and open /routing-demo.html", + "2. load a sample scenario", + "3. run routing comparison", + "4. review selected strategy/backend in Routing Proof Summary", + "5. compare scenario deltas", + "6. copy proof, walkthrough, association, or how-to summaries", + "7. follow evidence pages", + "8. export/copy/print packet from /evidence-export-packet.html", + "", + "howToReadEdgeCases:", + "- no previous scenario selected: packaged normal-load baseline remains the static reference", + "- same scenario run twice: strategy order and input signal totals should read as unchanged", + "- backend unchanged but signals changed: inspect the reason and visible scores/signals", + "- strategy changed but backend stayed the same: multiple methods can still prefer the same local candidate", + "- backend changed but strategy stayed the same: signal deltas can change which candidate the same strategy prefers", + "- all unhealthy/degraded scenario: treat it as a degradation boundary, not production proof", + "- empty comparison response: Local API returned an empty comparison response; static guidance remains available", + "- API unavailable/error: Local API response unavailable; static guidance remains available", + "- copy fallback: Copy failed; select the visible text and copy manually. Browser clipboard permission may be unavailable", + "- page loaded before interaction: static guidance and evidence links remain available before running a scenario", + "- evidence links before scenario execution: Evidence links are available even before running a scenario", + "", + "evidenceSupport:", + "- routingProofSummary: immediate decision view", + "- scenarioComparison: change over time/input states", + "- evidenceNavigationPath: " + evidenceNavigationPath(), + "- exportPacket: local reviewer handoff, not server-generated certification", + "- comparisonSignalSummary: " + comparisonSignals, + "- degradationRecoveryExplanation: " + degradation, + "", + "copyBoundary: browser-local copy action only; no upload/share endpoint; no server-side export/PDF/ZIP generation; no external calls; no telemetry", + "", + "notProven:", + "- no production traffic proof", + "- no live cloud proof", + "- no real tenant proof", + "- no registry publication proof", + "- no container signing proof", + "- no GitHub settings mutation proof", + "- no production certification claim", + "- no service-level agreement or service-level objective evidence" + ].join("\n"); + } + function resetDemo() { lastRoutingBody = null; lastRoutingError = ""; diff --git a/src/test/java/com/richmond423/loadbalancerpro/api/ReviewerTrustMapDocumentationTest.java b/src/test/java/com/richmond423/loadbalancerpro/api/ReviewerTrustMapDocumentationTest.java index 2c7083a3..45ac9b86 100644 --- a/src/test/java/com/richmond423/loadbalancerpro/api/ReviewerTrustMapDocumentationTest.java +++ b/src/test/java/com/richmond423/loadbalancerpro/api/ReviewerTrustMapDocumentationTest.java @@ -110,6 +110,7 @@ void reviewerTrustMapCoversPrimaryEvidencePaths() throws Exception { "PROXY_DEMO_FIXTURE_LAUNCHER.md", "routing-demo.html", "Reviewer Workflow Checklist", + "How This Proof Works", "Evidence Associations", "Association Legend", "Routing Proof Summary", @@ -150,6 +151,7 @@ void reviewerDemoPathAnswersFastDemoQuestionsAndLocksEvidenceFiles() throws Exce assertTrue(demoPath.contains("http://localhost:8080/routing-demo.html")); assertTrue(demoPath.contains("http://localhost:8080/load-balancing-cockpit.html")); assertTrue(demoPath.contains("Reviewer Workflow Checklist")); + assertTrue(demoPath.contains("How This Proof Works")); assertTrue(demoPath.contains("Evidence Associations")); assertTrue(demoPath.contains("Association Legend")); assertTrue(demoPath.contains("Routing Proof Summary")); @@ -163,6 +165,7 @@ void reviewerDemoPathAnswersFastDemoQuestionsAndLocksEvidenceFiles() throws Exce assertTrue(demoPath.contains("degradation/recovery notes")); assertTrue(demoPath.contains("local verification commands")); assertTrue(demoPath.contains("routing-to-evidence dashboard links")); + assertTrue(demoPath.contains("copyable how-to reviewer explanation")); assertTrue(demoPath.contains("copyable evidence association summary")); assertTrue(demoPath.contains("copyable end-to-end reviewer walkthrough")); assertTrue(demoPath.contains("explicit not-proven boundaries")); @@ -229,10 +232,17 @@ void routingDemoScenarioComparisonTrustMapEntryIsDiscoverableAndBounded() throws assertTrue(matrix.contains("How should a reviewer walk the routing cockpit end-to-end?")); assertTrue(matrix.contains("How do routing decisions connect to reviewer evidence pages?")); + assertTrue(matrix.contains("How should reviewers interpret routing proof details and edge cases?")); assertTrue(matrix.contains("How do routing proof scenarios compare?")); assertTrue(matrix.contains("/routing-demo.html")); assertTrue(matrix.contains("RoutingDecisionDemoTest")); assertTrue(matrix.contains("Reviewer Workflow Checklist")); + assertTrue(matrix.contains("How This Proof Works")); + assertTrue(matrix.contains("How to Interpret This Decision")); + assertTrue(matrix.contains("How to Reproduce This Proof")); + assertTrue(matrix.contains("How to Read Edge Cases")); + assertTrue(matrix.contains("How Strategy Choice Matters")); + assertTrue(matrix.contains("How Evidence Supports the Decision")); assertTrue(matrix.contains("Evidence Associations")); assertTrue(matrix.contains("Association Legend")); assertTrue(matrix.contains("Routing Proof Summary")); @@ -240,6 +250,7 @@ void routingDemoScenarioComparisonTrustMapEntryIsDiscoverableAndBounded() throws assertTrue(matrix.contains("Reviewer Confidence Signals")); assertTrue(matrix.contains("Evidence Navigation reviewer path")); assertTrue(matrix.contains("copyable evidence association summary")); + assertTrue(matrix.contains("copyable how-to reviewer explanation")); assertTrue(matrix.contains("selected scenario-to-decision mapping")); assertTrue(matrix.contains("selected strategy/backend mapping")); assertTrue(matrix.contains("key input signal mapping")); @@ -260,6 +271,9 @@ void routingDemoScenarioComparisonTrustMapEntryIsDiscoverableAndBounded() throws assertTrue(normalized.contains("edited local demo payloads")); assertTrue(normalized.contains("same-origin local api responses")); assertTrue(normalized.contains("browser-local copy text")); + assertTrue(normalized.contains("how the selected backend was chosen")); + assertTrue(normalized.contains("strategy and input signals influenced the proof")); + assertTrue(normalized.contains("edge cases should be read")); assertTrue(normalized.contains("upload/share endpoint behavior")); assertTrue(normalized.contains("server-side export/pdf/zip generation")); assertTrue(normalized.contains("production deployment certification")); @@ -271,6 +285,37 @@ void routingDemoScenarioComparisonTrustMapEntryIsDiscoverableAndBounded() throws assertTrue(normalized.contains("container signing")); } + @Test + void routingCockpitHowQuestionGuideTrustMapSectionIsDiscoverableAndBounded() throws Exception { + String trustMap = read(TRUST_MAP); + String section = section(trustMap, "### Cockpit How-Question Guide", "## Reviewer Demo Path"); + String normalized = section.toLowerCase(Locale.ROOT); + + assertTrue(section.contains("Cockpit How-Question Guide")); + assertTrue(section.contains("/routing-demo.html")); + assertTrue(section.contains("How This Proof Works panel")); + assertTrue(section.contains("interpret the selected decision")); + assertTrue(section.contains("reproduce the proof")); + assertTrue(section.contains("read edge cases")); + assertTrue(section.contains("understand strategy choice")); + assertTrue(section.contains("follow evidence support")); + assertTrue(section.contains("copyable how-to reviewer explanation")); + assertTrue(normalized.contains("browser-local text")); + assertTrue(normalized.contains("visible page guidance")); + assertTrue(normalized.contains("local comparison state")); + assertTrue(normalized.contains("no upload/share endpoint")); + assertTrue(normalized.contains("no server-side export/pdf/zip generation")); + assertTrue(normalized.contains("no external calls")); + assertTrue(normalized.contains("no telemetry")); + assertTrue(normalized.contains("no production traffic proof")); + assertTrue(normalized.contains("no live cloud proof")); + assertTrue(normalized.contains("no real tenant proof")); + assertTrue(normalized.contains("no registry publication proof")); + assertTrue(normalized.contains("no container signing proof")); + assertTrue(normalized.contains("no github settings mutation proof")); + assertTrue(normalized.contains("no production certification claim")); + } + @Test void routingCockpitEvidenceAssociationsTrustMapSectionIsDiscoverableAndBounded() throws Exception { String trustMap = read(TRUST_MAP); diff --git a/src/test/java/com/richmond423/loadbalancerpro/api/RoutingDecisionDemoTest.java b/src/test/java/com/richmond423/loadbalancerpro/api/RoutingDecisionDemoTest.java index 11c766ca..cec46617 100644 --- a/src/test/java/com/richmond423/loadbalancerpro/api/RoutingDecisionDemoTest.java +++ b/src/test/java/com/richmond423/loadbalancerpro/api/RoutingDecisionDemoTest.java @@ -111,15 +111,18 @@ void routingDemoPageContainsExpectedEndpointsControlsAndStrategyText() throws Ex assertTrue(page.contains("Routing proof summary -> supporting evidence pages")); assertTrue(page.contains("Evidence pages -> export packet / reviewer handoff")); assertTrue(page.contains("How This Proof Works")); - assertTrue(page.contains("How the selected strategy affects the selected backend")); - assertTrue(page.contains("How input signals influence the routing proof")); - assertTrue(page.contains("How scenario comparison deltas are summarized")); - assertTrue(page.contains("How degradation, unhealthy, and recovery states are represented")); - assertTrue(page.contains("How to reproduce the same proof locally")); - assertTrue(page.contains("How evidence pages relate to the proof")); - assertTrue(page.contains("How the copied association summary should be used")); - assertTrue(page.contains("How local/demo proof differs from production proof")); - assertTrue(page.contains("Edge-case reading guide")); + assertTrue(page.contains("Copy how-to reviewer explanation")); + assertTrue(page.contains("how-to-reviewer-output")); + assertTrue(page.contains("How to Interpret This Decision")); + assertTrue(page.contains("How was the selected backend chosen?")); + assertTrue(page.contains("How did the selected strategy influence the decision?")); + assertTrue(page.contains("How did input signals affect the proof?")); + assertTrue(page.contains("How should reviewers interpret confidence/limits?")); + assertTrue(page.contains("How does this differ from production proof?")); + assertTrue(page.contains("How Strategy Choice Matters")); + assertTrue(page.contains("How to Reproduce This Proof")); + assertTrue(page.contains("How Evidence Supports the Decision")); + assertTrue(page.contains("How to Read Edge Cases")); assertTrue(page.contains("Association Legend")); assertTrue(page.contains("scenario = demo input state")); assertTrue(page.contains("strategy = selected routing method")); @@ -400,19 +403,22 @@ void routingDemoHowToAndEdgeCasesAreExplicitReviewerGuidance() throws Exception String normalized = page.toLowerCase(Locale.ROOT); assertTrue(page.contains("id=\"reviewer-how-to-panel\"")); - assertTrue(page.contains("aria-label=\"Reviewer how-to explanation cards\"")); - assertTrue(page.contains("The first returned strategy is the primary local comparison result")); - assertTrue(page.contains("its routing rule ranks the visible candidate servers")); + assertTrue(page.contains("aria-label=\"How to interpret this decision cards\"")); + assertTrue(page.contains("The first returned comparison result is the primary local decision")); + assertTrue(page.contains("selected backend/server, includes returned reason text")); + assertTrue(page.contains("The selected strategy applies its scoring or selection behavior to the same visible candidates")); assertTrue(page.contains("Health, in-flight load, configured weight/capacity, p95 latency, error rate, queue depth, and network-awareness fields")); - assertTrue(page.contains("Deltas are browser-local summaries comparing packaged baseline metrics against the current editor payload")); + assertTrue(page.contains("Confidence means the browser can repeat the same local sample flow")); + assertTrue(page.contains("does not mean the result is approved for production use")); + assertTrue(page.contains("Run the app locally and open /routing-demo.html")); + assertTrue(page.contains("Run routing comparison to call the same-origin local /api/routing/compare endpoint")); + assertTrue(page.contains("Copy proof, walkthrough, association, or how-to summaries from visible browser text")); + assertTrue(page.contains("Routing Proof Summary is the immediate decision view")); + assertTrue(page.contains("Scenario Comparison shows change over time/input states")); + assertTrue(page.contains("Scenario comparison deltas are browser-local summaries")); assertTrue(page.contains("candidate count, healthy/unhealthy count, total in-flight load, max p95 latency, max error rate, and queue depth")); - assertTrue(page.contains("Unhealthy backends are counted from healthy=false")); - assertTrue(page.contains("all-unhealthy payloads are called out as a degradation boundary")); - assertTrue(page.contains("fewer unhealthy backends than the baseline are described as recovery")); - assertTrue(page.contains("Run mvn spring-boot:run")); - assertTrue(page.contains("reviewer, operator, timeline, and export packet pages provide navigation")); - assertTrue(page.contains("Use the copied association summary as a reviewer note")); - assertTrue(page.contains("it is not an audit artifact created by the server")); + assertTrue(page.contains("Evidence Navigation links related reviewer pages")); + assertTrue(page.contains("Export packet is a local reviewer handoff")); assertTrue(page.contains("Local/demo proof uses synthetic payloads, same-origin local API responses, and browser-local notes")); assertTrue(normalized.contains("does not prove production traffic")); assertTrue(normalized.contains("live cloud behavior")); @@ -437,6 +443,7 @@ void routingDemoEdgeCaseFallbackTextIsSpecificAndBrowserLocal() throws Exception assertTrue(page.contains("API error or unavailable local server: Local API response unavailable; static guidance remains available.")); assertTrue(page.contains("Copy-to-clipboard failure fallback: Copy failed; select the visible text and copy manually.")); assertTrue(page.contains("Static page loaded without prior interaction: static guidance and evidence links remain available before running a scenario.")); + assertTrue(page.contains("Evidence links before scenario execution: Evidence links are available even before running a scenario.")); assertTrue(page.contains("Local API returned HTTP ")); assertTrue(page.contains("Local API returned an empty comparison response; static guidance remains available.")); assertTrue(page.contains("Local API response unavailable; static guidance remains available.")); @@ -451,6 +458,45 @@ void routingDemoEdgeCaseFallbackTextIsSpecificAndBrowserLocal() throws Exception assertFalse(normalized.contains("automatic upload")); } + @Test + void routingDemoCopyableHowToReviewerExplanationIsBrowserLocalAndBounded() throws Exception { + String page = Files.readString(ROUTING_DEMO_PAGE, StandardCharsets.UTF_8); + String normalized = page.toLowerCase(Locale.ROOT); + + assertTrue(page.contains("Copy how-to reviewer explanation")); + assertTrue(page.contains("data-copy-target=\"how-to-reviewer-output\"")); + assertTrue(page.contains("# Cockpit How-To Reviewer Explanation")); + assertTrue(page.contains("howQuestionInventory:")); + assertTrue(page.contains("- already answered: selected strategy/backend, input signals, scenario deltas, degradation/recovery notes, evidence path, copy boundaries, and local/demo limits")); + assertTrue(page.contains("- clarified in this panel: interpretation sequence, reproduction steps, edge-case reading, strategy-choice effects, and evidence support boundaries")); + assertTrue(page.contains("howToInterpretThisDecision:")); + assertTrue(page.contains("- selectedBackendChosen: ")); + assertTrue(page.contains("- selectedStrategyInfluence: ")); + assertTrue(page.contains("- inputSignalsAffectingProof: ")); + assertTrue(page.contains("- confidenceLimits: local repeatability and deterministic visible inputs only; not production certification")); + assertTrue(page.contains("howToReproduceThisProof:")); + assertTrue(page.contains("1. run the app locally and open /routing-demo.html")); + assertTrue(page.contains("8. export/copy/print packet from /evidence-export-packet.html")); + assertTrue(page.contains("howToReadEdgeCases:")); + assertTrue(page.contains("- no previous scenario selected: packaged normal-load baseline remains the static reference")); + assertTrue(page.contains("- API unavailable/error: Local API response unavailable; static guidance remains available")); + assertTrue(page.contains("evidenceSupport:")); + assertTrue(page.contains("- routingProofSummary: immediate decision view")); + assertTrue(page.contains("- scenarioComparison: change over time/input states")); + assertTrue(page.contains("- evidenceNavigationPath: ")); + assertTrue(page.contains("- exportPacket: local reviewer handoff, not server-generated certification")); + assertTrue(page.contains("copyBoundary: browser-local copy action only; no upload/share endpoint; no server-side export/PDF/ZIP generation; no external calls; no telemetry")); + assertTrue(normalized.contains("no production traffic proof")); + assertTrue(normalized.contains("no live cloud proof")); + assertTrue(normalized.contains("no real tenant proof")); + assertTrue(normalized.contains("no registry publication proof")); + assertTrue(normalized.contains("no container signing proof")); + assertTrue(normalized.contains("no github settings mutation proof")); + assertTrue(normalized.contains("no production certification claim")); + assertFalse(normalized.contains("server-side how-to export")); + assertFalse(normalized.contains("telemetry upload")); + } + @Test void routingDemoAssociationLegendExplainsProofTermsWithoutCertificationClaim() throws Exception { String page = Files.readString(ROUTING_DEMO_PAGE, StandardCharsets.UTF_8);