688 lines
21 KiB
Markdown
688 lines
21 KiB
Markdown
# GEO Agent Article Optimizer MVP Design
|
|
|
|
## Goal
|
|
|
|
Build a lightweight internal web tool for optimizing pasted GEO-related articles while preventing the issues observed in `GEO生成文章改动点(0422).docx`: industry drift, image-text mismatch, third-party voice in official articles, platform mismatch, incomplete company names, title/body grammar issues, hallucinated claims, inconsistent claims, context-insensitive sensitive-word handling, and useless content.
|
|
|
|
The first version validates the content quality loop before investing in batching, permissions, publishing integrations, or complex document parsing.
|
|
|
|
## MVP Scope
|
|
|
|
The MVP is a local web application:
|
|
|
|
1. User pastes title, body, image descriptions or image links, and selects the target platform.
|
|
2. System extracts a candidate fact card.
|
|
3. User confirms or edits the fact card.
|
|
4. Confirmed fact card is saved as a reusable local brand template.
|
|
5. System optimizes the article under fact-card constraints.
|
|
6. System runs quality gates.
|
|
7. Failed checks trigger targeted rewriting for up to two rounds.
|
|
8. User previews optimized content and QA report.
|
|
9. User downloads Markdown and a basic Word document.
|
|
10. User can optionally register where an optimized revision was published and later record real performance data for calibration.
|
|
|
|
## Explicitly Out Of Scope
|
|
|
|
- Account permissions.
|
|
- Multi-user collaboration.
|
|
- Publishing platform APIs.
|
|
- Batch queues.
|
|
- Direct `.docx` upload parsing.
|
|
- Complex Word template layout.
|
|
- Automatic use of unconfirmed facts.
|
|
- Automatic platform performance adapters in the first calibration release. The first release records performance manually while keeping an adapter interface for later.
|
|
|
|
## User Flow
|
|
|
|
```mermaid
|
|
flowchart TD
|
|
A["Input Article"] --> B["Auto Analyze"]
|
|
B --> C["Confirm Fact Card"]
|
|
C --> D["Optimize Article"]
|
|
D --> E["Quality Check"]
|
|
E -->|Pass| F["Preview Result"]
|
|
E -->|Fail| G["Targeted Rewrite"]
|
|
G --> D
|
|
F --> H["Download Markdown / Word"]
|
|
```
|
|
|
|
## Page Areas
|
|
|
|
### Article Input
|
|
|
|
Fields:
|
|
|
|
- Title.
|
|
- Body.
|
|
- Image description or image link.
|
|
- Target platform: official site, media article, comparison review, recommendation list.
|
|
- User instructions.
|
|
|
|
The first version accepts pasted text instead of `.docx` upload to avoid early complexity around Word layout parsing.
|
|
|
|
### Fact Card Confirmation
|
|
|
|
The system extracts candidate facts, but they are not treated as truth until the user confirms them.
|
|
|
|
Fields:
|
|
|
|
- Company full name.
|
|
- Company short names.
|
|
- Brand names.
|
|
- Product names.
|
|
- Target industry.
|
|
- Target audience.
|
|
- Experience years.
|
|
- Core claims.
|
|
- Forbidden claims.
|
|
- Image topics.
|
|
- Uncertain items.
|
|
|
|
The user must resolve uncertain items before optimization starts.
|
|
|
|
### Optimized Result
|
|
|
|
Display:
|
|
|
|
- Optimized title.
|
|
- Summary.
|
|
- Optimized body.
|
|
- Image suggestions.
|
|
- Changed sections.
|
|
|
|
The UI should mark content that needs user confirmation.
|
|
|
|
### Quality Report
|
|
|
|
Display each gate as pass, warn, or fail, with evidence, reason, suggested fix, and target rewrite module.
|
|
|
|
### Export
|
|
|
|
Downloads:
|
|
|
|
- `optimized.md`
|
|
- `optimized.docx`
|
|
- `qa_report.json`
|
|
|
|
## Internal Agent Nodes
|
|
|
|
The product is delivered as a simple web app, but the internals are split into explicit workflow nodes.
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
A["InputNormalizer"] --> B["FactExtractor"]
|
|
B --> C["UserConfirmedFactCard"]
|
|
C --> D["ArticleOptimizer"]
|
|
D --> E["QualityInspector"]
|
|
E -->|fail| F["TargetedRewriter"]
|
|
F --> E
|
|
E -->|pass/warn| G["Exporter"]
|
|
```
|
|
|
|
### LLM Provider Integration
|
|
|
|
Workflow nodes use a local LLM client abstraction instead of calling a vendor API directly. The first implementation uses DeepSeek by default, while keeping the provider boundary open for later OpenAI-compatible providers.
|
|
|
|
Environment variables:
|
|
|
|
```text
|
|
LLM_PROVIDER=deepseek
|
|
DEEPSEEK_API_KEY=
|
|
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
|
DEEPSEEK_MODEL=deepseek-v4-pro
|
|
DEEPSEEK_THINKING=disabled
|
|
```
|
|
|
|
Rules:
|
|
|
|
- `src/lib/llm/client.ts` exposes `generateText`, `generateJson<T>`, `isLlmConfigured`, and `getLlmProviderStatus`.
|
|
- `LLM_PROVIDER` defaults to `deepseek` when unset.
|
|
- DeepSeek is accessed through the OpenAI-compatible SDK with `baseURL` set to `https://api.deepseek.com`.
|
|
- `generateJson<T>` must use JSON output mode and prompts that explicitly require valid JSON only.
|
|
- Thinking mode is disabled by default for deterministic article rewrites and structured QA output.
|
|
- Missing credentials use deterministic local fallbacks so the MVP remains testable and usable without a live API key.
|
|
- Provider errors are normalized inside the LLM client before they reach workflow nodes or API routes.
|
|
|
|
### InputNormalizer
|
|
|
|
Purpose: normalize page input into clean structured data.
|
|
|
|
Input:
|
|
|
|
- Title.
|
|
- Body.
|
|
- Image descriptions or links.
|
|
- Target platform.
|
|
- User instructions.
|
|
|
|
Output:
|
|
|
|
- `article_draft`
|
|
- `image_assets`
|
|
- `publish_context`
|
|
|
|
This node does not optimize content.
|
|
|
|
### FactExtractor
|
|
|
|
Purpose: extract candidate facts from the source article.
|
|
|
|
Output:
|
|
|
|
- `company_full_name`
|
|
- `company_short_name`
|
|
- `brand_names`
|
|
- `product_names`
|
|
- `target_industry`
|
|
- `target_audience`
|
|
- `experience_years`
|
|
- `core_claims`
|
|
- `forbidden_claims`
|
|
- `image_topics`
|
|
- `uncertain_items`
|
|
|
|
Low-confidence facts must go into `uncertain_items`.
|
|
|
|
### UserConfirmedFactCard
|
|
|
|
Purpose: provide hard constraints for all downstream nodes.
|
|
|
|
Rules:
|
|
|
|
- No downstream node may invent numbers, qualifications, clients, cases, or experience years outside the confirmed fact card.
|
|
- Company and product names must follow the fact card.
|
|
- Industry and audience must not drift from the fact card.
|
|
- Sensitive words must be handled by context, not removed mechanically.
|
|
|
|
### ArticleOptimizer
|
|
|
|
Purpose: improve title, summary, body, structure, and image suggestions under fact-card constraints.
|
|
|
|
Allowed:
|
|
|
|
- Improve fluency.
|
|
- Fix grammar.
|
|
- Adjust structure.
|
|
- Improve platform fit.
|
|
- Remove useless content.
|
|
- Improve transitions.
|
|
|
|
Forbidden:
|
|
|
|
- Invent claims.
|
|
- Change company or product names.
|
|
- Change industry.
|
|
- Add exaggerated marketing promises.
|
|
|
|
### QualityInspector
|
|
|
|
Purpose: convert the document's issue list into executable quality gates.
|
|
|
|
Each check returns:
|
|
|
|
- `status`: `pass`, `warn`, or `fail`.
|
|
- `evidence`: source or optimized text snippet.
|
|
- `reason`: why the check passed or failed.
|
|
- `suggested_fix`: how to fix it.
|
|
- `target_agent`: rewrite target when failed.
|
|
|
|
### TargetedRewriter
|
|
|
|
Purpose: fix only failed checks.
|
|
|
|
Examples:
|
|
|
|
- Rewrite only the title for title quality failures.
|
|
- Adjust only the affected paragraph for body quality failures.
|
|
- Normalize company names for fact consistency failures.
|
|
- Delete or mark unsupported claims for hallucination risk.
|
|
- Warn instead of rewriting when image-text confidence is low.
|
|
|
|
### PerformanceCalibrator
|
|
|
|
Purpose: turn exported GEO articles into a measurable quality-improvement loop after publication.
|
|
|
|
This node is optional and runs after the optimization/export workflow. It does not rewrite the article, does not change the confirmed fact card, and does not block export. It records a pre-publication scoring snapshot, a publication record, post-publication performance snapshots, and calibration observations that can later improve GEO scoring rubrics.
|
|
|
|
Inputs:
|
|
|
|
- Optimized article revision.
|
|
- QA report for the same revision.
|
|
- Publish platform and optional URL.
|
|
- Manual performance data in the first release.
|
|
|
|
Outputs:
|
|
|
|
- `scoring_run`
|
|
- `publication_record`
|
|
- `performance_snapshot`
|
|
- `calibration_event`
|
|
|
|
Rules:
|
|
|
|
- Calibration is append-only for a published revision. Later data imports create new snapshots instead of overwriting earlier ones.
|
|
- The first release uses manual data entry only.
|
|
- The service boundary must support future adapters that return the same `PerformanceSnapshot` shape.
|
|
- Adapter code must never store platform cookies, tokens, or login state in the public repository.
|
|
- Calibration observations can recommend rubric changes, but rubric changes require a separate reviewed migration or plan.
|
|
|
|
## Quality Gates
|
|
|
|
| Rule ID | Issue Prevented | First Version Behavior |
|
|
| --- | --- | --- |
|
|
| `industry_alignment` | Industry drift | Compare article against fact-card industry and audience. |
|
|
| `image_text_match` | Image-text mismatch | Compare image descriptions/topics with nearby article sections. |
|
|
| `voice_consistency` | Third-party voice in official articles | Enforce platform-specific tone. |
|
|
| `platform_fit` | Wrong article type for platform | Compare style and structure against target platform. |
|
|
| `company_name_integrity` | Incomplete company name | Compare against confirmed company full name and allowed short names. |
|
|
| `title_quality` | Title grammar issues | Detect awkward, keyword-stuffed, or semantically broken titles. |
|
|
| `body_quality` | Body grammar issues | Detect long sentences, unclear references, and broken logic. |
|
|
| `hallucination_risk` | Fabricated or misleading claims | Reject claims not traceable to the confirmed fact card. |
|
|
| `claim_consistency` | Inconsistent years/products/services | Scan and normalize repeated factual claims. |
|
|
| `context_sensitive_terms` | Blind sensitive-word deletion | Warn when wording needs context-aware handling. |
|
|
|
|
### Hard Fail
|
|
|
|
- Incomplete or inconsistent company name.
|
|
- New numbers, qualifications, customer cases, or other claims outside the fact card.
|
|
- Clear industry drift.
|
|
- Severe title grammar failure.
|
|
- Conflicting experience years, product names, or service names.
|
|
|
|
### Warn
|
|
|
|
- Low-confidence image-text match.
|
|
- Uncertain sensitive-word context.
|
|
- Weak platform fit.
|
|
- Overly promotional or low-density paragraphs.
|
|
|
|
### Auto Fix
|
|
|
|
- Body grammar.
|
|
- Useless content.
|
|
- Third-party voice when platform is official site.
|
|
|
|
## Publication Performance Calibration
|
|
|
|
The project can borrow the useful part of `cheat-on-content`: content quality should become a measurable loop, not a one-time rewrite. GEO's version keeps the web app and database model, and adds a productized calibration layer instead of copying the external skill's file-based workflow.
|
|
|
|
First-release flow:
|
|
|
|
```mermaid
|
|
flowchart LR
|
|
A["Optimized Article Revision"] --> B["Pre-Publish Scoring"]
|
|
B --> C["Publication Record"]
|
|
C --> D["Manual Performance Snapshot"]
|
|
D --> E["Calibration Event"]
|
|
E --> F["Rubric Improvement Backlog"]
|
|
```
|
|
|
|
### Pre-Publish Scoring
|
|
|
|
Before or after export, the system can score an optimized revision against a GEO rubric. The first rubric should focus on business article quality rather than viral-video prediction.
|
|
|
|
Suggested first dimensions:
|
|
|
|
| Dimension | Meaning |
|
|
| --- | --- |
|
|
| `fact_integrity` | Whether names, products, years, cases, and claims stay inside the confirmed fact card. |
|
|
| `platform_fit` | Whether the output matches official site, media article, comparison review, or recommendation list expectations. |
|
|
| `search_intent_fit` | Whether the article answers the likely GEO/search intent behind the topic. |
|
|
| `answer_density` | Whether the article gives useful, specific information instead of vague promotional filler. |
|
|
| `trust_signal_quality` | Whether credibility signals are specific, sourced, and not exaggerated. |
|
|
| `readability` | Whether title, summary, and body are clear enough for customers and AI answer engines. |
|
|
|
|
The score is stored as a snapshot. It is not a replacement for QA gates. QA gates protect factual safety; scoring provides a baseline for later performance learning.
|
|
|
|
### Publication Records
|
|
|
|
A publication record links one optimized article revision to where it was published.
|
|
|
|
Fields:
|
|
|
|
- Job ID.
|
|
- Optimized revision.
|
|
- Platform.
|
|
- URL.
|
|
- Published at.
|
|
- Publication notes.
|
|
- Status: draft, published, archived.
|
|
|
|
The same optimized revision may have multiple publication records if a user republishes it on multiple channels.
|
|
|
|
### Manual Performance Snapshots
|
|
|
|
The first release records post-publication performance manually. This avoids platform login, anti-scraping, and credential risk while validating the calibration loop.
|
|
|
|
Baseline fields:
|
|
|
|
- Views or reads.
|
|
- Impressions, when available.
|
|
- Clicks or inquiry actions, when available.
|
|
- Likes, comments, shares, saves, when available.
|
|
- Average ranking or citation position, when the user can observe it.
|
|
- Snapshot window, such as T+1d, T+3d, T+7d, or custom.
|
|
- Comment or feedback summary.
|
|
- Data source: `manual`.
|
|
|
|
Manual snapshots should allow missing metrics. Different platforms expose different numbers, and forcing fake zeroes would corrupt later calibration.
|
|
|
|
### Adapter Boundary
|
|
|
|
Future adapters must write the same performance shape as manual entry:
|
|
|
|
```ts
|
|
interface PerformanceAdapter {
|
|
source: string;
|
|
fetch(input: AdapterFetchInput): Promise<PerformanceSnapshot>;
|
|
}
|
|
```
|
|
|
|
Adapter output is normalized before storage:
|
|
|
|
- `source`: `manual`, `adapter:xhs`, `adapter:bilibili`, `adapter:wechat`, or similar.
|
|
- `metrics`: sparse numeric metrics.
|
|
- `snapshot_at`: ISO timestamp.
|
|
- `window_label`: human label such as `T+3d`.
|
|
- `raw_reference`: optional safe reference to adapter output, never raw cookies or credentials.
|
|
|
|
The first implementation should include a `manual` adapter only. Platform adapters are later work and must keep credentials out of Git, D1, logs, and public artifacts.
|
|
|
|
### Calibration Events
|
|
|
|
A calibration event compares the pre-publish scoring snapshot, QA report, and performance snapshot.
|
|
|
|
Examples:
|
|
|
|
- High `fact_integrity` and high `answer_density` correlate with stronger inquiry clicks.
|
|
- Weak `platform_fit` correlates with poor engagement on media articles.
|
|
- QA warning on `hallucination_risk` did not affect traffic but increased manual review burden.
|
|
- Articles with high readability but low trust-signal quality received views but no inquiries.
|
|
|
|
Calibration events should be written as observations, not automatic rubric changes. A later rubric update must be reviewed separately and applied through migrations/tests so historical data remains interpretable.
|
|
|
|
## Data Model
|
|
|
|
The first version uses local SQLite plus an export folder. Cloudflare deployments use D1/R2 bindings with migration-only schema changes; local and online data remain explicitly separated.
|
|
|
|
```text
|
|
data/
|
|
app.db
|
|
exports/
|
|
job_xxx/
|
|
original.md
|
|
optimized.md
|
|
optimized.docx
|
|
qa_report.json
|
|
```
|
|
|
|
### `brand_template`
|
|
|
|
Reusable confirmed brand facts.
|
|
|
|
```json
|
|
{
|
|
"id": "brand_xxx",
|
|
"brand_name": "Brand",
|
|
"company_full_name": "Company Ltd.",
|
|
"company_short_names": ["Company"],
|
|
"product_names": ["Product"],
|
|
"target_industries": ["GEO optimization"],
|
|
"target_audience": ["Marketing teams"],
|
|
"verified_claims": ["More than ten years of industry experience"],
|
|
"forbidden_claims": ["Do not claim industry first without proof"],
|
|
"tone_rules": {
|
|
"official_site": "brand first-person or official voice",
|
|
"media": "objective third-party voice"
|
|
},
|
|
"updated_at": "2026-06-16T10:00:00+08:00"
|
|
}
|
|
```
|
|
|
|
### `article_job`
|
|
|
|
One optimization task.
|
|
|
|
```json
|
|
{
|
|
"id": "job_xxx",
|
|
"brand_template_id": "brand_xxx",
|
|
"source_title": "Original title",
|
|
"source_body": "Original body",
|
|
"image_inputs": [
|
|
{
|
|
"type": "description",
|
|
"content": "Product dashboard screenshot"
|
|
}
|
|
],
|
|
"publish_platform": "official_site",
|
|
"status": "qa_failed",
|
|
"created_at": "2026-06-16T10:05:00+08:00"
|
|
}
|
|
```
|
|
|
|
### `fact_card`
|
|
|
|
Confirmed facts for one job.
|
|
|
|
```json
|
|
{
|
|
"job_id": "job_xxx",
|
|
"source": "auto_extract_then_user_confirmed",
|
|
"company_full_name": "Company Ltd.",
|
|
"product_names": ["Product"],
|
|
"target_industry": "GEO optimization",
|
|
"publish_intent": "official article",
|
|
"locked_claims": ["More than ten years of industry experience"],
|
|
"uncertain_items": [],
|
|
"confirmed_by_user": true
|
|
}
|
|
```
|
|
|
|
### `optimized_article`
|
|
|
|
One revision of optimized content.
|
|
|
|
```json
|
|
{
|
|
"job_id": "job_xxx",
|
|
"revision": 2,
|
|
"title": "Optimized title",
|
|
"summary": "Optimized summary",
|
|
"body_markdown": "Optimized body in Markdown",
|
|
"image_suggestions": [
|
|
{
|
|
"source": "image_1",
|
|
"suggestion": "Use product dashboard screenshot; avoid unrelated people photos"
|
|
}
|
|
],
|
|
"changed_sections": ["title", "first paragraph"]
|
|
}
|
|
```
|
|
|
|
### `qa_report`
|
|
|
|
Quality checks for one revision.
|
|
|
|
```json
|
|
{
|
|
"job_id": "job_xxx",
|
|
"revision": 2,
|
|
"overall_status": "warn",
|
|
"checks": [
|
|
{
|
|
"rule_id": "hallucination_risk",
|
|
"status": "pass",
|
|
"evidence": "No new unsupported factual claims found",
|
|
"reason": "All factual claims are traceable to the confirmed fact card",
|
|
"target_agent": null
|
|
}
|
|
]
|
|
}
|
|
```
|
|
|
|
### `rubric_version`
|
|
|
|
A versioned scoring rubric for GEO article performance calibration.
|
|
|
|
```json
|
|
{
|
|
"id": "rubric_geo_v1",
|
|
"version": "v1",
|
|
"name": "GEO article performance rubric",
|
|
"dimensions": [
|
|
{
|
|
"id": "fact_integrity",
|
|
"label": "事实一致性",
|
|
"weight": 2,
|
|
"description": "事实、公司名、产品名和经验年限是否遵守事实卡"
|
|
}
|
|
],
|
|
"formula": "weighted_average_0_to_10",
|
|
"is_active": true,
|
|
"created_at": "2026-06-24T10:00:00+08:00"
|
|
}
|
|
```
|
|
|
|
### `scoring_run`
|
|
|
|
A scoring snapshot for one optimized article revision.
|
|
|
|
```json
|
|
{
|
|
"id": "score_xxx",
|
|
"job_id": "job_xxx",
|
|
"revision": 2,
|
|
"rubric_version_id": "rubric_geo_v1",
|
|
"dimension_scores": {
|
|
"fact_integrity": 5,
|
|
"platform_fit": 4,
|
|
"search_intent_fit": 4,
|
|
"answer_density": 3,
|
|
"trust_signal_quality": 3,
|
|
"readability": 4
|
|
},
|
|
"composite_score": 7.8,
|
|
"rationale": "事实一致性强,平台适配较好,但信任信号仍偏泛。",
|
|
"created_at": "2026-06-24T10:05:00+08:00"
|
|
}
|
|
```
|
|
|
|
### `publication_record`
|
|
|
|
A publication instance for an optimized revision.
|
|
|
|
```json
|
|
{
|
|
"id": "pub_xxx",
|
|
"job_id": "job_xxx",
|
|
"revision": 2,
|
|
"platform": "official_site",
|
|
"url": "https://example.com/articles/geo-optimization",
|
|
"published_at": "2026-06-24T12:00:00+08:00",
|
|
"status": "published",
|
|
"notes": "官网文章首发"
|
|
}
|
|
```
|
|
|
|
### `performance_snapshot`
|
|
|
|
One post-publication performance measurement.
|
|
|
|
```json
|
|
{
|
|
"id": "perf_xxx",
|
|
"publication_id": "pub_xxx",
|
|
"source": "manual",
|
|
"window_label": "T+7d",
|
|
"metrics": {
|
|
"views": 1200,
|
|
"impressions": 4300,
|
|
"clicks": 86,
|
|
"inquiries": 7,
|
|
"likes": 18,
|
|
"comments": 3,
|
|
"shares": 5,
|
|
"saves": 11
|
|
},
|
|
"feedback_summary": "用户主要询问服务流程和案例真实性。",
|
|
"snapshot_at": "2026-07-01T12:00:00+08:00"
|
|
}
|
|
```
|
|
|
|
### `calibration_event`
|
|
|
|
An observation linking scoring, QA, and real performance.
|
|
|
|
```json
|
|
{
|
|
"id": "cal_xxx",
|
|
"publication_id": "pub_xxx",
|
|
"scoring_run_id": "score_xxx",
|
|
"performance_snapshot_id": "perf_xxx",
|
|
"direction": "better_than_expected",
|
|
"observations": [
|
|
"高 answer_density 的段落带来更多服务流程咨询。",
|
|
"trust_signal_quality 偏低,用户仍追问案例依据。"
|
|
],
|
|
"recommended_action": "后续 rubric 提高 trust_signal_quality 权重前,先积累至少 5 篇同类样本。",
|
|
"created_at": "2026-07-01T12:10:00+08:00"
|
|
}
|
|
```
|
|
|
|
## Error Handling
|
|
|
|
### Fact Extraction
|
|
|
|
Optimization is disabled until the user resolves uncertain facts.
|
|
|
|
Examples:
|
|
|
|
- Only a company short name is found.
|
|
- Multiple product names appear.
|
|
- Multiple experience-year claims appear.
|
|
- Target industry is unclear.
|
|
- Image description is missing.
|
|
|
|
### QA Failure
|
|
|
|
QA failures do not hide exports. Hard failures and warnings are surfaced as risk signals with visible confirmation prompts, so the user can still download artifacts for review or customer handoff.
|
|
|
|
Failed checks trigger targeted rewrite for up to two rounds. After two failed rounds, the app stops rewriting and shows manual review fields.
|
|
|
|
### Performance Data
|
|
|
|
Manual performance snapshots accept sparse metrics. Missing metrics are stored as absent values, not zeroes.
|
|
|
|
Adapter failures must degrade to manual entry. The app should show the source and failure reason, but it must not block the user from recording performance data manually.
|
|
|
|
Calibration events never rewrite published articles automatically. They create a reviewable backlog for future rubric changes.
|
|
|
|
## Acceptance Criteria
|
|
|
|
The MVP is complete when:
|
|
|
|
1. User can paste title, body, image descriptions, and target platform.
|
|
2. System can extract a fact card and require user confirmation.
|
|
3. Confirmed fact card can be saved and reused as a local brand template.
|
|
4. System can generate an optimized article without changing confirmed facts.
|
|
5. System can generate a structured QA report for the 10 quality gates.
|
|
6. Hard failures and warnings are visible in the QA report without hiding export links.
|
|
7. User can download Markdown and a basic Word document.
|
|
8. User can create a publication record for an optimized revision.
|
|
9. User can manually record a post-publication performance snapshot.
|
|
10. System can create a calibration event that compares score, QA findings, and performance.
|
|
11. The performance collection boundary can later support platform adapters without changing the stored snapshot shape.
|
|
|
|
## Minimum Test Samples
|
|
|
|
Prepare at least five sample articles:
|
|
|
|
1. Industry drift sample.
|
|
2. Incorrect or incomplete company name sample.
|
|
3. Title grammar sample.
|
|
4. Conflicting experience-year sample.
|
|
5. Image-text mismatch sample.
|
|
|
|
These samples cover the most important risks from the source document and keep the first validation loop focused.
|