Repository navigation
Description
Problem
scripts/research_workflow.py's init command (scaffold()) reads the --outline JSON file with a bare json.loads(...) (research_workflow.py:243-244) and then uses the parsed value's fields raw. Sibling inputs in the same tool were hardened in #6854 (profile/state/trigger shapes) and #6857 (note/resolution shapes), but the outline — the file that seeds a new research package's title, concepts, and state — was not covered. A valid-JSON-but-wrong-shape (or non-JSON) outline therefore surfaces as a bare Python error that names neither the file nor the field, instead of the tool's own fail() diagnostic used everywhere else in the file. The CLI (main(), research_workflow.py:1079-1088) catches these types, so the run exits 1 with e.g.:
$ research_workflow.py init --input transcript.txt --slug x --outline outline.json
error: 'list' object has no attribute 'get'
— an operator cannot tell which field of which file is malformed.
Evidence (verified this run, laptop @ 65beb42, real files verbatim, probe ~/git/fleet/probe-rw-scaffold-outline/)
The probe copies scripts/research_workflow.py (+ its two extension modules) verbatim from origin/main (md5 match), builds a fixture repo root with a valid profile, and drives the real CLI (init --allow-duplicate, 2-line transcript).
Control: a well-formed outline (object with string title, one concept with string title/slug/summary and source_lines: [[1, 2]]) scaffolds successfully (rc=0, package created). No malformed case creates a partial package.
Wrong shapes (all raw, none via fail()):
- Outline top level
[]→error: 'list' object has no attribute 'get';"x"→ same forstr—outline.get("title", "")at research_workflow.py:262 runs before any isinstance guard. - Outline
title: 42→error: expected string or bytes-like object, got 'int'—re.search(...)on the unchecked title at :262. - Concept entry
"just-a-string"→error: 'str' object has no attribute 'get'—concept.get("title")at :271. - Concept
slug: 42→error: expected string or bytes-like object, got 'int'—slug()runsre.fullmatchon the unchecked value (:276 → :121-124). An explicit"slug": nulltakes the same path. - Concept
summary: 42→error: can only concatenate str (not "int") to str—summaryis concatenated raw at :355 (itsthoughts/suggestionssiblings ARE validated as string lists at :294-298;summaryis not). - Outline file containing non-JSON (
not json{) →error: Expecting value: line 1 column 1 (char 0)— the barejson.loadsat :244; the message names no file.
Why it matters
The outline is the machine-generated seed for every new research package (produced by the research-prepare step and handed to init); a truncated or mis-shaped generation is exactly the corruption this tool's fail() idiom exists to diagnose precisely. Today the operator gets a type error with no file, no field, and no expected shape, and must read the source to find which of the outline's fields is wrong. This is one more instance of the #3068 parsed-is-not-validated pattern, in the one research_workflow.py input surface #6854/#6856/#6857 did not reach.
Acceptance criteria
scaffold()validates the outline before use: non-object top level, non-JSON body, non-stringtitle/introduction, non-object concept entries, non-string conceptslug, and non-string conceptsummaryeach fail viafail()with a message naming the outline file and the field/expectation.- Validation happens before any package directory is created (today's no-partial-package property is preserved).
- Regression tests in
scripts/tests/test_research_workflow.pycover each wrong shape above and assert the cleanfail()diagnostic. - A valid outline behaves byte-identically to today (existing test suite green; the probe control above still scaffolds).
Activity
developing-today commentedon Nov 7, 2026
CODE-2130
dezren39 commentedon Nov 7, 2026
🤖 Agent note · filed
init --outlineJSON shape in scripts/research_workflow.py's scaffold() with the tool's fail() idiom — top level, title/introduction, concept entries, slug and summary are used raw today, so wrong shapes and non-JSON fail with bare type errors naming no file or field. Verified this run on the laptop @ 65beb42 (probe ~/git/fleet/probe-rw-scaffold-outline, real files verbatim + real CLI: 7 wrong shapes raw, valid-outline control OK, no partial package).developing-today commentedon Nov 8, 2026
🤖 Agent note · picked up
5 remaining items
dezren39 commentedon Nov 8, 2026
🤖 Agent note · picked up
Merge pull request #7015 from developing-today/queue/11095-6862-outli…
dezren39 commentedon Nov 8, 2026
🤖 Agent note · done