Skip to content

I3310 — majordomus start refuses a task, owner or reason that the task record cannot hold, and writes nothing

Refuse at entry, with a usage exit and no write, any task description, --owner or --because value that is multi-line, carries a control character, or would not round-trip through the layer's YAML reader; adr propose, decision add, knowledge observe and question add/resolve already refuse multi-line text through mj_is_multiline.

READY wave 0 · p2 · implementation profile · parallel safe

Part of failure-is-visible — Every failure the runtime can suffer is bounded, tested or stated, and changes the health it reports.

Ready. Every dependency is done, so majordomus plan start I3310 will be accepted.

Objective

Refuse at entry, with a usage exit and no write, any task description, --owner or --because value that is multi-line, carries a control character, or would not round-trip through the layer's YAML reader; adr propose, decision add, knowledge observe and question add/resolve already refuse multi-line text through mj_is_multiline.

Why

lib/start.sh:144 and :150 write task, owner and exemption_because into .ai/local/state/current.yaml as double-quoted scalars, escaping the double quote in task and because and nothing in owner, and lib/start.sh never calls mj_is_multiline (lib/common.sh:1788). The layer's YAML reader rejects multi-line scalars (lib/common.sh:767), so a task started with an embedded newline, a trailing backslash or a quote in --owner writes a record that the next check, handover or finish cannot parse. The refusal belongs at the boundary that accepts the text (2026-09-04 archive review). Sources: chatgpt-majordomus:c003#4.

Current state

At 707a04c, start accepts any argument text. grep -n mj_is_multiline lib/*.sh lists the callers: adr propose, decision add, knowledge observe and question add/resolve refuse multi-line text; lib/start.sh is not among them.

Desired state

One shared predicate judges every scalar a task command writes, start applies it to task, owner and because, and a refused start leaves no state behind.

Scope

  • lib/start.sh
  • lib/common.sh
  • docs/CLI.md

Out of scope

  • Changing the task record's schema
  • Rewriting existing task records

Dependencies

None. This issue is a root of the graph.

Acceptance criteria

  • majordomus start with a newline in the task exits with the usage code and writes no current.yaml
  • The same refusal covers --owner and --because
  • A quote, a backslash and a non-ASCII letter in the task are stored and read back unchanged by check
  • A case drives each refusal and each round trip in a disposable repository

Validation

  • bash test/run.sh 04_start_check

Evidence required

  • case_start_refuses_unsafe_scalars

Evidence

None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.

Timeline

started
—
verified
—
completed
—

Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.

Canonical record: .ai/repo/project/issues/I3310.yaml. Read it back with majordomus plan show I3310.

Searches the titles and descriptions of every page this site publishes.