|
| 1 | +--- |
| 2 | +title: "Fetch full content clobbers the operator's metadata — resets the title to a URL approximation" |
| 3 | +lede: "Clicking 'Fetch full content' on a source overwrites the title (and publisher/date/authors) the operator typed, replacing it with Jina's guess or — when Jina fails — the raw URL. Enrichment must be additive: fetch the body, fill only empty fields, never overwrite accepted metadata." |
| 4 | +date_created: 2026-08-02 |
| 5 | +date_modified: 2026-08-02 |
| 6 | +authors: |
| 7 | + - Michael Staton |
| 8 | +augmented_with: |
| 9 | + - Claude Code on Claude Opus 4.8 |
| 10 | +semantic_version: 0.0.0.1 |
| 11 | +tags: |
| 12 | + - Issue |
| 13 | + - Augment-It |
| 14 | + - Strategy-Curator |
| 15 | + - Corpus |
| 16 | + - Bug |
| 17 | +status: Resolved |
| 18 | +--- |
| 19 | + |
| 20 | +# Fetch full content clobbers the operator's metadata |
| 21 | + |
| 22 | +## Why Care? |
| 23 | + |
| 24 | +Surfaced live 2026-08-02. The operator fills in a source's metadata (title, |
| 25 | +publisher, date), clicks **Fetch full content**, and the title resets to an |
| 26 | +approximation of the URL — the hand-entered value is gone. Worse, a |
| 27 | +URL-shaped title is the *failure* signal: it means Jina couldn't read the |
| 28 | +page, so the content probably wasn't fetched either. Two bugs stacked, and |
| 29 | +the clobber hid the failure. Violates the standing rule that additive |
| 30 | +enrichment never overrides accepted fields ([[feedback_additive_enrichment_never_overrides_accepted]]). |
| 31 | + |
| 32 | +## Root cause — three layers |
| 33 | + |
| 34 | +1. **`fetchSourceContent` (content-ingest/corpus.ts):** |
| 35 | + `const title = jr.ok ? jr.title || args.url : args.url` — never consulted |
| 36 | + the operator's saved title; Jina's guess (or the URL on failure) always |
| 37 | + won. Bib fields likewise merged "Jina wins, fall back to file." |
| 38 | +2. **`applyBibToRegistry` (resolver):** wrote that Jina/URL title straight |
| 39 | + onto the canonical `sources` row. |
| 40 | +3. **Client `fetchSource` (curation.svelte.ts):** merged the fetch result |
| 41 | + *over* the form (`{ ...source, ...r.source }`), so the clobbered title |
| 42 | + landed back in the field. |
| 43 | + |
| 44 | +## Desired behavior (operator's spec, 2026-08-02) |
| 45 | + |
| 46 | +Keep all form metadata as-is → fetch full content → write to SurrealDB with |
| 47 | +workspace access (humain-vc) → return the `sources` uuid → write local |
| 48 | +markdown *if local-write is enabled*. |
| 49 | + |
| 50 | +Of these: DB write + client scoping (`source_usages.client_slug`) and the |
| 51 | +returned `source_uuid` already exist. This issue covers the **metadata |
| 52 | +preservation** half. The **local-write toggle** is tracked separately (spec |
| 53 | +addendum to [[Strategy-Curator-Entry-Point-for-Augment-It]]). |
| 54 | + |
| 55 | +## Fix |
| 56 | + |
| 57 | +- `fetchSourceContent` reads the operator's saved `title` (and bib) from the |
| 58 | + source file and treats them as authoritative; Jina's values are demoted to |
| 59 | + fallbacks that fill only empty fields. The existing `source_slug` is |
| 60 | + preserved so a re-fetch never renames the file. |
| 61 | +- Client `fetchSource` keeps the operator's title/authors/publisher/date and |
| 62 | + takes only content + status from the fetch; and now surfaces |
| 63 | + "fetch failed — could not read the URL" instead of silently resetting. |
| 64 | + |
| 65 | +## Resolution |
| 66 | + |
| 67 | +Fixed 2026-08-02. Verified: `rsbuild build` (strategy-curator) + `tsc |
| 68 | +--noEmit` (content-ingest) both green. Reaches augment.didi.sh on the next |
| 69 | +redeploy. |
| 70 | + |
| 71 | +## See also |
| 72 | + |
| 73 | +- [[feedback_additive_enrichment_never_overrides_accepted]] |
| 74 | +- [[feedback_human_in_drivers_seat]] — web-research output isn't trusted to overwrite operator input. |
0 commit comments