Skip to content

MCP: an assistant can author models with no docs pasted in - #21

Merged
sajonaro merged 3 commits into
mainfrom
mcp-authoring
Oct 3, 2026
Merged

sajonaro merged 3 commits into
mainfrom
mcp-authoring

Conversation

@sajonaro

@sajonaro sajonaro commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Implements the feature request in mcp_advanced.md (R1–R8). An LLM client with no Writ knowledge can now learn the language from the server, send models inline, fix errors from the error alone, and be told when a model is too big.

What changes

  • Inline sources (R1). Every path argument has a *_source twin, at most 256 KB. Inline text is served as inline:NAME.writ, a name no (load …) can reach, so an inline model can never stand in for a library that pinned claims load. claims_source is refused under --claims-dir. model_name keeps revision history per name for as long as the server runs. Inline writ_compare and writ_query must be given claims, since an inline model has no sibling .claims file.
  • writ_guide (R2). Topics index, syntax.model, syntax.claims, syntax.rules, semantics (it answers the request's 11 questions), idioms, and five worked examples: mutex, webhooks, consumer, commit, handoff. Each example shows the failing check, the fix and the compare. There is also one topic per error code. The topics are markdown in tooling/mcp/guide/, compiled into the server. The largest is about 2k tokens.
  • Instructions, inline example, resources, prompt (R3, R4, R8).
  • writ_validate (R5). Parses and type-checks without building the space, then summarises types, arrows, laws, moves, properties and relations, plus the situation bound. It warns when the bound is over budget. A misspelt name in claims, which writ_check would answer n/a, is an error here.
  • Coded errors (R6). Each error carries a code, its source, line and column, found and expected names, a hint, a corrected fix line for a misspelt name, and a pointer to its guide topic. Codes are assigned in one table (diagnose.ml), and a test proves each code's wrong example still raises it. One error per file: the front ends stop at the first.
  • Limits (R7). max_situations (default 200000, at most 2000000) and timeout_ms (default 60000). A search that is cut off returns E_STATE_LIMIT with how far it got, the bound, every property marked undecided, and the cells that grew most.
  • writ_compare now ends with the properties still failing in both models, so a fix that fixed nothing doesn't look clean.
  • Matches 0.4.0. The MCP check counts n/a as a finding, as writ check now does.

Breaking

A transition clause other than when or do is now an error. A bare (set …) outside (do …) used to be dropped silently, leaving a move that changed nothing. None of the 70 models across writ, writ-problems, writ-arch and writ-scheduling-verification has one.

Also

docs/interrogator.md §2's can-reach base case lacked (situation S); holds does not bind its situation, so the rule was rejected.

Also: report readability and certification

  • A failing inevitable shows how a run avoids its goal. It prints avoids: the run stops at #N when the run stops, or loop: the shortest cycle back to the stuck situation. Under (fair …) it prints loops among: the situations a fair run circles in.
  • Long dead-end lists are shortened in the text report. A route of more than 24 moves keeps its first and last 10 and gives the count of the rest; after 20 dead ends the report gives the count of the remainder. --json still lists every dead end.
  • certified no longer suggests n/a claims were checked. When every property is n/a and no query was asked, the line reads certified: the situation count only — every property is n/a, so no claim was checked. This applies to both writ check and writ_check.
  • None of these change --json or the certificate format, so writ-cert needs no change.
  • The plugin's SKILL.md mentions writ_guide and writ_validate for servers that list them. It still reads correctly against the pinned 0.4.0 image.

Testing

  • make build, make lint and make test pass. test_mcp_authoring has 231 checks: it re-runs every guide example against its printed output, and every error code's wrong and right example. test_report_json covers the n/a certified line.
  • A fresh agent was given only the tools, with no server instructions. It passed the six acceptance scenarios: cold authoring, error recovery, property kinds, regression catch, witness inspection, and too-large. Its findings and a separate code review are fixed in this PR.
  • make downstream: all six suites pass (problems, crosscheck, arch, scheduling, mgtt2writ, vscode) with PROBLEMS_REF=queens-count-from-json. Merge queens: count complete boards from --json writ-problems#15 first. Its queens check counted the complete boards in the text dead-end list, which this PR now cuts off at 20.

🤖 Generated with Claude Code

sajonaro and others added 3 commits October 3, 2026 21:41
The MCP server could run a model someone else wrote but not teach a client to
write one: tools took only paths (a chat client cannot write to the server's
disk), no instructions were set, and errors were prose. This implements the
feature request in mcp_advanced.md, R1-R8:

- inline sources beside every path argument, served as `inline:NAME.writ`,
  a name no (load …) can reach, so pinned claims stay pinned; model_name keeps
  revision history per inline model; claims_source is refused under
  --claims-dir;
- writ_guide: index, syntax.model/claims/rules, semantics, idioms, five worked
  examples (failing check, fix, compare) and one topic per error code, as
  markdown in tooling/mcp/guide embedded at build time; also writ://guide
  resources and a writ_model_system prompt; server instructions; a complete
  example in writ_check's description;
- writ_validate: parse and type-check without building the space, with a
  summary and the situation bound; a misspelt name in claims, which check
  would answer n/a, is an error here, and check adds a `why n/a` line;
- coded errors (code, position, found, expected, hint, corrected line, guide
  pointer), as prose or JSON;
- max_situations / timeout_ms, and a cut-off search that reports how far it
  got and which cells grew, deciding nothing;
- writ_compare names properties still failing in both models.

Breaking: a transition clause other than when/do is an error; a bare (set …)
outside (do …) was silently dropped. No model in the writ repositories has
one.

test_mcp_authoring re-runs every guide example against its printed output and
every error code's wrong and right example. A cold-start agent given only the
tools passed the request's six acceptance scenarios; its findings and a code
review are folded in.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The cold-start acceptance run found that a failing inevitable said only
`stuck at: #N` — not how a run avoids the goal from there — and that dead-end
routes of hundreds of moves flooded a reply.

- inevitable: `avoids: the run stops at #N`, or `loop:` a shortest cycle back
  to the stuck situation outside F; under (fair …), where one cycle could
  starve a fair move, `loops among:` the region a fair run circles in.
  Space.avoidance exposes the region escapes_f already computed.
- dead ends: a route over 24 moves keeps its ends and counts the middle; past
  20 dead ends the rest are counted.
- Prose only; --json and certificates are unchanged (certified as before).
- plugin skill: mention writ_guide/writ_validate when the server lists them,
  so it reads true against the pinned 0.4.0 image and later ones.
- docs/mcp.md: an inline model's (load …) searches the working directory
  first, as a path model's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
With every property n/a and no query, writ-cert re-derives only the
situation count, yet the last line read "every answer re-derived". It now
reads `certified: the situation count only — every property is n/a, so no
claim was checked`, in `writ check` and `writ_check` alike (one renderer,
Certify_json.verdict_line). The certification JSON field and the
certificate format are unchanged, so writ-cert needs nothing.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@sajonaro
sajonaro merged commit a5ddd20 into main Oct 3, 2026
7 of 8 checks passed
@github-actions github-actions Bot locked and limited conversation to collaborators Oct 3, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant