Neutral AI badge fallback and docs for configurable prompts #103

Manually merged
marvin8 merged 2 commits from feat/issue-100-badge-and-docs into feat/issue-100-generic-ai-classification 2026-08-22 07:16:20 +00:00
Collaborator

Sub-PR 3 of 3 for the domain-agnostic AI classification effort (#100).

What

  • Review-page AI reject badge fallback: AI: reject — promotionalAI: reject — text — a reject with no vision category is a text-stage reject, and "promotional" presumes the cat-topic default.
  • Docs sweep to the neutral field names (text_flagged / vision_accepted): docs/architecture/models.md, docs/architecture/design.md, docs/user-guide/automated-scheduling.md.
  • docs/user-guide/ai-classification.md: documents the editable prompts (settings-page textareas, JSON contract appended by code, future-fetches-only semantics) and the neutral verdict fields; badge table updated.
  • Removed the stale Nightly AI Vision Batch section from automated-scheduling.md (the Moonshot Batch API pipeline no longer exists — classification runs inline on each fetch batch) and the last mention in review.md; automated-scheduling.md overview and fetch-pipeline sections now include the AI classification steps.
  • Docstring neutrality sweep in ai_classification.py / ai_pipeline.py.

Notes

  • docs/api/posts.md needed no change — it documents only the unchanged field names.

Refs #100

Sub-PR 3 of 3 for the domain-agnostic AI classification effort (#100). ## What - Review-page AI reject badge fallback: `AI: reject — promotional` → `AI: reject — text` — a reject with no vision category is a text-stage reject, and "promotional" presumes the cat-topic default. - Docs sweep to the neutral field names (`text_flagged` / `vision_accepted`): `docs/architecture/models.md`, `docs/architecture/design.md`, `docs/user-guide/automated-scheduling.md`. - `docs/user-guide/ai-classification.md`: documents the editable prompts (settings-page textareas, JSON contract appended by code, future-fetches-only semantics) and the neutral verdict fields; badge table updated. - Removed the stale Nightly AI Vision Batch section from `automated-scheduling.md` (the Moonshot Batch API pipeline no longer exists — classification runs inline on each fetch batch) and the last mention in `review.md`; `automated-scheduling.md` overview and fetch-pipeline sections now include the AI classification steps. - Docstring neutrality sweep in `ai_classification.py` / `ai_pipeline.py`. ## Notes - `docs/api/posts.md` needed no change — it documents only the unchanged field names. Refs #100
💄 neutral AI badge fallback and docs sweep
All checks were successful
/ gitleaks (pull_request) Successful in 20s
/ pr-review (pull_request) Successful in 2m12s
/ checks (pull_request) Successful in 2m39s
/ publish (pull_request) Has been skipped
/ publish-container (pull_request) Has been skipped
/ deploy-docs (pull_request) Has been skipped
40831d0eb2
The reject badge falls back to 'text' when no vision category
is set (was 'promotional'), and the docs now describe the
configurable prompts and the neutral text_flagged /
vision_accepted semantics.
📝 remove stale nightly AI batch docs, document inline classification
All checks were successful
/ gitleaks (pull_request) Successful in 18s
/ pr-review (pull_request) Successful in 2m12s
/ checks (pull_request) Successful in 2m24s
/ publish (pull_request) Has been skipped
/ publish-container (pull_request) Has been skipped
/ deploy-docs (pull_request) Has been skipped
6a21023424
The Moonshot Batch API pipeline was tried and removed; classification
now runs inline on each fetch batch. automated-scheduling.md loses the
Nightly AI Vision Batch section and cron bullet, gains AI steps in the
overview and fetch pipeline; review.md drops the last batch mention.
forgejo-actions left a comment

WuMing

Found 2 issue(s). See inline comments below.

## WuMing Found **2** issue(s). See inline comments below.
@ -916,0 +922,4 @@
"""A reject with no vision category renders the text-stage label."""
view = ReviewLiveView()
view.socket = MagicMock()
badge = view._render_ai_badge({"ai_would_reject": True, "vision_category": None})

code [HIGH]

The post dict passed to _render_ai_badge omits ai_classified_at. Based on the pending return immediately above the changed reject branch in liveviews.py, _render_ai_badge likely returns the 'AI: pending' badge when ai_classified_at is absent, so this assertion never reaches the reject fallback label and the test will fail. Add a truthy ai_classified_at value (e.g., datetime.utcnow()) to the dict.

**code** [HIGH] The post dict passed to _render_ai_badge omits ai_classified_at. Based on the pending return immediately above the changed reject branch in liveviews.py, _render_ai_badge likely returns the 'AI: pending' badge when ai_classified_at is absent, so this assertion never reaches the reject fallback label and the test will fail. Add a truthy ai_classified_at value (e.g., datetime.utcnow()) to the dict. <!-- wuming:sha256:52a3ae22f171d8f054ea5327e902111481e761192bf5f0939efde43834dff44b -->
marvin8 marked this conversation as resolved
@ -916,0 +931,4 @@
"""A vision-stage reject renders the model's category."""
view = ReviewLiveView()
view.socket = MagicMock()
badge = view._render_ai_badge({"ai_would_reject": True, "vision_category": "comic"})

code [HIGH]

Same issue as the first test: the post dict omits ai_classified_at, so _render_ai_badge is likely to take the pending path and never render the vision category reject badge. Add a truthy ai_classified_at field to exercise the reject branch.

**code** [HIGH] Same issue as the first test: the post dict omits ai_classified_at, so _render_ai_badge is likely to take the pending path and never render the vision category reject badge. Add a truthy ai_classified_at field to exercise the reject branch. <!-- wuming:sha256:c588a65ba223ab5851f9d88bfd697adc9277e58d4fcd5d6472935401092668e9 -->
marvin8 marked this conversation as resolved
Author
Collaborator

🔴 Not actioned — _render_ai_badge does not read ai_classified_at

tests/test_liveviews.py · tests/test_liveviews.py

_render_ai_badge likely returns the 'AI: pending' badge when ai_classified_at is absent, so this assertion never reaches the reject fallback label and the test will fail…

Two pieces of evidence against:

  1. The code has no ai_classified_at check. _render_ai_badge branches only on ai_would_reject: the pending badge is returned when post.get("ai_would_reject") is None. Both tests pass ai_would_reject: True, so the reject branch runs. ai_classified_at appears nowhere in the function (verified by reading the source and grepping the function body).
  2. The tests demonstrably execute the reject branch. Both were written red-then-green: before the fix, the fallback test failed with the old label AI: reject — promotional; after changing the fallback to text it passes. If the pending path were taken, "AI: reject — text" in badge would fail — the full suite is green (556 tests).
### 🔴 Not actioned — `_render_ai_badge` does not read `ai_classified_at` [`tests/test_liveviews.py`](https://forge.marvin8.zone/marvin8/dujiangyan/pulls/103#issuecomment-1867) · [`tests/test_liveviews.py`](https://forge.marvin8.zone/marvin8/dujiangyan/pulls/103#issuecomment-1868) > _render_ai_badge likely returns the 'AI: pending' badge when ai_classified_at is absent, so this assertion never reaches the reject fallback label and the test will fail… Two pieces of evidence against: 1. **The code has no `ai_classified_at` check.** `_render_ai_badge` branches only on `ai_would_reject`: the pending badge is returned when `post.get("ai_would_reject") is None`. Both tests pass `ai_would_reject: True`, so the reject branch runs. `ai_classified_at` appears nowhere in the function (verified by reading the source and grepping the function body). 2. **The tests demonstrably execute the reject branch.** Both were written red-then-green: before the fix, the fallback test failed with the old label `AI: reject — promotional`; after changing the fallback to `text` it passes. If the pending path were taken, `"AI: reject — text" in badge` would fail — the full suite is green (556 tests).
marvin8 approved these changes 2026-08-22 07:15:58 +00:00
marvin8 manually merged commit 513be5c139 into feat/issue-100-generic-ai-classification 2026-08-22 07:16:20 +00:00
marvin8 deleted branch feat/issue-100-badge-and-docs 2026-08-22 07:16:29 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
marvin8/dujiangyan!103
No description provided.