Files
AILang/docs/plans/0040-ms.1.md
T
Brummel 832375f2ac convention: counter-prefix file naming across docs/specs/, docs/plans/, design/contracts/, design/models/
All 176 files in the four accumulating directories now use a
zero-padded 4-digit counter prefix that reflects creation order
(`NNNN-slug.md`). The counter is assigned per directory in strict
git-log creation order; ties broken alphabetically by original name.
The old `YYYY-MM-DD-` prefix on docs/specs/ and docs/plans/ files is
dropped — the date is recoverable from git log and the counter
carries the ordering.

A file's counter is stable for the life of the file: never reassigned,
never reused, never compacted. Deleted files retire their counter;
subsequent files do not fill the gap. This is the property that lets
cross-references stay literal — refs use the full filename including
the counter (`design/contracts/0007-honesty-rule.md`) so they grep
cleanly and resolve directly without a glob step.

313 cross-references updated across .md/.rs/.toml/.c/.json files
(test pins, include_str! paths, design-INDEX entries, baseline notes,
runtime C comments, inter-contract markdown links incl. bare basename
and `../models/foo.md` forms).

CLAUDE.md gets a new "File-naming convention" section spelling out
the rule and rationale. skills/brainstorm/SKILL.md and
skills/planner/SKILL.md updated so new spec/plan creation produces
counter-prefixed names from the start.

The full test suite (cargo test --workspace) passes.
2026-05-28 13:31:31 +02:00

6.5 KiB

ms.1 — Pipeline anyhow-chain preservation — Implementation Plan

Parent spec: docs/specs/0018-multi-subject-codellama.md

For agentic workers: REQUIRED SUB-SKILL: use skills/implement to run this plan. Steps use - [ ] checkboxes for tracking.

Goal: Fix the JSON-cohort feedback bug where harness-side module_name_from_json failures lose their Caused by: chain on the way into the model prompt. Change is two characters, gated by a RED→GREEN unit test.

Architecture: pipeline.rs:118 formats an anyhow::Error with {e} (Display), which prints only the top-level message. The underlying serde-parse-error sits in the cause chain and is dropped. Switch to {e:#} (alternate Display), which joins the chain with : separators on a single line — survives the existing strip_locations regex (which only collapses \nCaused by: blocks, not : -joined chains) and lands a fully informative diagnostic in the model's next-turn prompt.

Tech Stack: Rust 1.x, anyhow, serde_json, xmodel_harness::pipeline.

Files this plan creates or modifies:

  • Modify: experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs:118 — change format!("check: {e}") to format!("check: {e:#}")
  • Modify: experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs — add (or extend if present) #[cfg(test)] mod tests block with the RED→GREEN test

Recon note (Boss-direct, no agent dispatch): the iter touches one file at one line; the Boss verified the current source verbatim during the brainstorm session (see iter journal). ailang-plan-recon dispatch skipped — context already loaded.


Task 1: RED test — anyhow chain preservation

Files:

  • Modify: experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs — add #[cfg(test)] mod tests if not present, or extend if present

  • Step 1: Add the failing test

At the bottom of pipeline.rs, add:

#[cfg(test)]
mod tests {
    use anyhow::{anyhow, Context, Error};

    /// Constructs the same chain shape `module_name_from_json`
    /// produces on a serde-parse failure: a leaf error wrapped
    /// with a "parsing JSON in <path>" context. Asserts that the
    /// format string used at pipeline.rs error-emission preserves
    /// both layers.
    #[test]
    fn check_format_preserves_anyhow_chain() {
        let leaf: Error = anyhow!("expected value at line 1 column 1");
        let chained = Err::<(), _>(leaf)
            .context("parsing JSON in /tmp/x.ail.json")
            .unwrap_err();
        let formatted = format!("check: {chained:#}");
        assert!(
            formatted.contains("parsing JSON in /tmp/x.ail.json"),
            "top-level context missing; got: {formatted}",
        );
        assert!(
            formatted.contains("expected value at line 1 column 1"),
            "leaf cause missing; got: {formatted}",
        );
    }
}
  • Step 2: Run the test — verify it does NOT compile or fails informatively

Run: cargo test --manifest-path experiments/2026-05-12-cross-model-authoring/harness/Cargo.toml check_format_preserves_anyhow_chain

Expected: the test PASSES because we wrote {chained:#} directly in the test body, NOT because we're calling the production formatter. This is acceptable — the test pins the property that {:#} preserves the chain. The actual RED-GREEN dance happens in Task 2 below, where the production line at pipeline.rs:118 is changed.

Reviewer note: a more direct RED-first test would call a Boss-extractable formatter helper from production code and assert against it. The current production code inlines the format string at the call site (format!("check: {e}") is local to a match arm), and extracting it to a helper just for testability would be over-engineering for a two-character fix. The pinning test in this task plus the manual code-path inspection in Task 2 together close the loop.

Task 2: GREEN — switch pipeline.rs:118 to alternate Display

Files:

  • Modify: experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs:118

  • Step 1: Read the current line

Run: sed -n '115,122p' experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs

Expected output (verbatim):

        Err(e) => {
            return Ok(PipelineCapture {
                error: Some(format!("check: {e}")),
                stdout: String::new(),
                stderr: e.to_string(),
            });
        }
  • Step 2: Apply the change

In pipeline.rs:118, change:

                error: Some(format!("check: {e}")),

to:

                error: Some(format!("check: {e:#}")),

(Two-character delta: {e}{e:#}. No other lines change.)

  • Step 3: Re-read to confirm

Run: sed -n '115,122p' experiments/2026-05-12-cross-model-authoring/harness/src/pipeline.rs

Expected output (verbatim):

        Err(e) => {
            return Ok(PipelineCapture {
                error: Some(format!("check: {e:#}")),
                stdout: String::new(),
                stderr: e.to_string(),
            });
        }
  • Step 4: Run the unit test from Task 1

Run: cargo test --manifest-path experiments/2026-05-12-cross-model-authoring/harness/Cargo.toml check_format_preserves_anyhow_chain

Expected: PASS.

Task 3: Full harness test sweep — no regressions

Files: (none modified; verification only)

  • Step 1: Run the full harness test suite

Run: cargo test --manifest-path experiments/2026-05-12-cross-model-authoring/harness/Cargo.toml

Expected: 14 passed (the previous 13 + the new check_format_preserves_anyhow_chain). Suite breakdown:

  • inline --lib unit tests: 6 (5 strip_locations + 1 new pipeline)

  • integration strip_locations: 5

  • integration verify_references: 1

  • integration mock_full_run: 1

  • integration budget_abort: 1

  • Step 2: cargo check the crate

Run: cargo check --manifest-path experiments/2026-05-12-cross-model-authoring/harness/Cargo.toml

Expected: clean (no new warnings introduced by the edit).


Per-iter journal entry

After all tasks complete, write docs/journals/2026-05-12-iter-ms.1.md (≤200 words) covering:

  • What the bug was and how it was discovered (during ms.2 planning recon)
  • Why {:#} is the right fix (alternate Display joins chain with : , survives strip_locations)
  • Why this was a separate iter from ms.2 (precedes the live IONOS spend; cheap fix should land before any further runs)
  • Test count after: 14 (up from 13)

Add a one-line entry to docs/journals/INDEX.md pointing at the new file.