Skip to content

[Feat] Add the five-stage Jev content desk with a draft Omni worker path - #96

Draft
hsliuustc0106 wants to merge 1 commit into
mainfrom
cursor/jev-content-workflow-79f8
Draft

hsliuustc0106 wants to merge 1 commit into
mainfrom
cursor/jev-content-workflow-79f8

Conversation

@hsliuustc0106

Copy link
Copy Markdown
Contributor

Required human contributor answers

Answers are taken from the task that asked for the diagram “我现在的 Jev 工作流” / “Jev 做筛选,人做决定”, and from the follow-up that set the agents×omni split. They are not a new rationale.

  1. What outcome are you trying to achieve?

    Answer: A supported five-stage content workflow in system1-agents: ingest RSS and Twitter/X (or fixtures), Jev screens, a person picks 3–5 items, Jev fact-checks, and a person decides whether to publish. Add an agents×omni demo path for the screen and fact-check steps. Do not auto-publish.

  2. What is the highest-leverage variable for that outcome?

    Answer: The agreed split, built on the existing ticket_router / s1a decide pattern rather than a new tool loop. system1-agents owns orchestration, RSS/X ingest (or fixtures), the human pick gate, and the human publish gate. system1-omni only provides HTTP workers for the screen and fact-check classify/score steps.

  3. How will this work move that variable rather than create busywork?

    Answer: A small client points at a configurable Omni serve base URL, so draft workers can be used without merging system1-omni #164–#166. The default worker is StartLux Instant 4B (#164). Fact-check can switch to PPLX (#166). Clef (#165) stays off the hot path. When OMNI_BASE_URL is unset, a local/fixture decider runs so CI stays offline. About 50 labeled items record choice and score against labels. A Public231-C1-style latency gate is documented for later and is not attached.

  4. Who is the customer or user, and what do they actually need?

    Answer: The person in that desk diagram. Jev screens and fact-checks. The person picks what to research and decides whether to publish.

After answering the four questions: is a PR needed at all to achieve this outcome?

Human decision and rationale (or explicit source reference): Yes. The task asked to add this path in system1-agents, open a PR, and not merge it.

For a bug fix: link actual observed failure evidence.

Evidence: Not applicable. This adds a workflow. It does not fix a reported failure.

Why

There is no runnable path for the five-stage desk. Jev can answer an enumerated choice, and ticket_router already batches that kind of decision, but nothing ingests a feed, stops for a person, fact-checks a draft, and records a publish decision without posting. A shared tool-loop agent would keep acting after each choice, so the two human gates would not be able to stop the run.

How

The desk is a separate command, python -m s1a.content. It is not a SPEC agent, so s1a list, the smoke agent list, and the MCP tool list stay as they are.

Review order:

  1. s1a/content/workflow.py — stage order and the two gates. human_publish.executed is always []. auto_publish is always false.
  2. s1a/content/omni_client.py — short POST /v1/systemone prefills. StartLux sends think_mode: never. PPLX sends thinking: {"enabled": false} and needs its own URL. Clef is refused. No retries. Error text does not include the response body.
  3. s1a/content/rules.py — offline lexical baseline used when no Omni URL is set. Labels are stripped before the decider sees an item.
  4. s1a/content/ingest.py — RSS 2.0 and Atom from a file or an opt-in URL. X is a JSONL fixture. The unconfigured adapter does not call api.x.com and does not read X_BEARER_TOKEN.
  5. s1a/content/__main__.py and s1a/content/latency.py — CLI exits and the unattached latency hook.
  6. tests/test_content_workflow.py and recipes/content-workflow/.

--backend auto uses Omni only when OMNI_BASE_URL is set. Otherwise it uses the lexical rule. Explicit --picks and --publish win over hooks. Hooks win over --allow-unsafe-skip-gates. That flag invents a pick and holds every item. It still does not publish.

Authored Python is 2,044 added lines (s1a/content 1,511, tests/test_content_workflow.py 533) and 0 deleted lines. The full diff is 2,502 insertions and 1 deletion, including docs and the fixture. That is under the 3,000-line authored-code threshold.

What

  • New package s1a/content and CLI python -m s1a.content run / latency-report.
  • Recipe recipes/content-workflow: 50 labeled items (32 keep / 18 drop, 8 drafts), pick and publish files, local RSS and X fixtures.
  • Docs: docs/content-workflow.md, plus rows in the recipe index, agents, capabilities, configuration, skills, README, .env.example, and CHANGELOG Unreleased.
  • Callers set OMNI_BASE_URL (and, for PPLX, OMNI_FACTCHECK_BASE_URL) only when a draft worker is already serving. No new dependency. No new MCP tool. s1a decide does not gain a score question.

Verification

Commands run on this branch before the commit, parent 9b20b989d919bc69227f81bc0ec571ca56925586:

  • uv run ruff format --check . && uv run ruff check . && uv run ty check — passed
  • uv run pytest -q — 1160 passed, 130 skipped, 250 subtests passed. scripts/smoke.sh — smoke: ok. The agent list is still the existing nine names; this path is not a SPEC agent.
  • CHANGELOG.md and docs/content-workflow.md describe the command, the gates, and the unattached latency hook.

Fixture command (rule profile, no decision socket):

OMNI_BASE_URL= OMNI_API_KEY= uv run python -m s1a.content run \
  --items recipes/content-workflow/items.jsonl \
  --picks recipes/content-workflow/picks.json \
  --publish recipes/content-workflow/publish.json \
  --backend rule \
  > runs/recipes/content-workflow/report.json

The recipe verifier printed n01 -> supported score 2 decision publish, n02 -> unsupported score 0 decision publish, n03 -> needs_human score 1 decision hold, n04 -> supported score 2 decision hold, screen 50 / 50, and Verified the fixture workflow; nothing was published. The same command without --picks exited 2 with human pick gate on stderr. Counts are in recipes/content-workflow/smoke-evidence.json. The full report stays under gitignored runs/. The lexical rule matches these labels by construction. That is a wiring check, not a quality result for Jev, StartLux, or PPLX.

Not run: a live StartLux or PPLX worker, s1a decide against Jev, and any latency ceiling. latency_gate.attached is false. No p50 is pinned. StartLux’s recorded Public231 number is a different workload and is not this fixture’s budget.

Demo / evidence

  • Video link, or exemption/blocker with follow-up: No application + System1-Agents + System1-Omni clip. Blocker: no draft worker was served in this environment, and system1-omni #164 and #166 are unmerged drafts. A rule-backend terminal run does not fill that gap. This PR stays a draft until that clip exists or a maintainer accepts the exception. The clip should show the fixture items, the worker’s choice and score, the human pick and publish files, executed: [], and the answering model, request id, and base URL from the same run.
  • Application/task → agent actions → independently checked result: Fixture input recipes/content-workflow/items.jsonl (sha256 51828b6671f507e4ce635d90a43420b1855fde864c43dfc17c072e3ba983f064) → lexical screen of 50/50 against labels, human pick n01–n04, fact-check of those four drafts against their stored claims, human decisions from publish.json including publish on an unsupported item → human_publish.executed is [] and auto_publish is false. Recorded at 2026-10-25T02:08:22Z on parent 9b20b98, in the working tree that added the recipe. Re-run on this head (46e74be10f00ee437517d3580701caeb23ca615f) to refresh the note. Mock StartLux (think_mode: never) and PPLX (thinking.enabled: false) transports are covered in tests/test_content_workflow.py and do not open a worker socket.
  • System1-Agents / System1-Omni commits, checkpoint and worker/frontend provenance: Agents head 46e74be10f00ee437517d3580701caeb23ca615f, base 9b20b989d919bc69227f81bc0ec571ca56925586. No System1-Omni commit, checkpoint, or worker was used. The client names draft workers only: StartLux Instant 4B, model StartLux-Decision-v1.1-4B-Instant, system1-omni #164; optional fact-check model perplexity-ai/pplx-decider-v1.1-27b, system1-omni #166. Clef #165 is refused. Neither draft has to be merged. CI on this head was not observed at submit time.
Open in Web Open in Cursor 

The desk ingests RSS and fixture posts, screens keep or drop, waits for a
human pick, fact-checks the picked drafts, and records a publish decision
without posting. OMNI_BASE_URL sends short /v1/systemone prefills to a draft
StartLux worker; PPLX is an optional fact-check URL. Unset, the lexical rule
runs offline so CI does not need a worker.

Co-authored-by: Hongsheng Liu <liuhongsheng4@huawei.com>

@Birfy Birfy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review (Birfy): comment only, draft

Head 46e74be1, merge base is current main (9b20b98). I re-ran it locally on that head: ruff check clean, pytest -q 1160 passed, 130 skipped, 250 subtests passed, matching the PR. CI is green. The two gates do what the description says: human_publish.executed is always [], auto_publish is always false, and a missing --picks stops at the pick gate.

Points to address before this leaves draft:

  1. The System1-Omni worker PRs are merged now, so the "draft" framing is stale. InferMatrixLab/system1-omni #164 (StartLux, merged 2026-10-25 07:21 UTC), #166 (PPLX, 07:22 UTC) and #165 (Clef, 08:15 UTC) all landed after this branch was cut. worker_record() still writes "draft": True, "merged_required": False, and omni_client.py, docs/content-workflow.md and the recipe README say "draft worker" throughout (46 mentions of "draft" in s1a/content + the doc, though some mean the article draft). Please point at the merged commits (dd7bfd0, f18b8a6, a41e379) or a pinned system1-omni tag, and drop the draft/merged_required fields or make them reflect the actual state.
  2. No Jev path despite the title. s1a/content never imports build_model or anything in s1a/decision_models; --backend is auto | rule | omni, and the Omni workers are StartLux and PPLX. So "the five-stage Jev content desk" can't run on Jev, Laya or Cua. Either route the screen and fact-check questions through the existing decision-model factory (the ticket_router pattern the description cites, so --model jev|laya|cua works and you get the shared validation and provenance for free), or retitle and say in the docs that Jev is not wired yet.
  3. Repo naming. The new code and docs link InferMatrixLab/system1-omni, while the README and the rest of docs/ use ThinkFlowLab/system1-omni (GitHub redirects, it's the same repo). Pick one across the repo, or note the rename in the CHANGELOG, so readers don't think there are two Omni projects.
  4. Evidence for leaving draft. The fixture run is, as the PR says, a wiring check: the lexical rule matches the labels by construction. Before ready-for-review, a short live run of the screen step against a serving StartLux worker on the 50 labeled items (choice accuracy and p50 latency), plus the recording the repo asks for, would give reviewers a real number.

Small: smoke-evidence.json is committed but the full report is under gitignored runs/. Fine, but say in the recipe README how to regenerate the evidence file so it doesn't drift.

Not approving while draft. Nothing here blocks the design; (1) and (2) are what I'd want fixed first.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants