Skip to content

Manual Facts — 2026-10-05

🤖 AI Drafted (Not reviewed)

The user manual belongs to the maintainer (see Writing the Guides). This page supplies facts for him to write from. It covers five features merged up to integration at a3363fc94. Every fact cites the code it was read from. Paths are relative to the repository root. The app is fichero/fichero/, the engine is fichero-server/src/fichero_server/ (written server/ below) and the MCP server is fichero-mcp/src/fichero_mcp/.

Each section has the same five parts:

  • What a person can do
  • Names on screen: the exact menu and button names
  • What they see
  • Defaults taken, awaiting a ruling
  • Screenshots wanted

Where something is not built, the section says so.


1. Setting up a project

Spec: specs/source/models-chains-and-projects.md. The maintainer’s section will be “Setting up a project”.

What a person can do

  • Answer five questions about a project: its purpose, its material, what it is, how it will be done, and Start.
  • Fichero proposes a recipe from the answers. Nothing runs until the person presses Start.
  • Leaving any of the first four screens with Continue saves a draft. Reopening setup picks the draft up again.
  • Later, they can add a language or a layer to the project from the Inspector’s Recipe section.

Where it is reached

  • File › Set Up Project… (App/Menus/FileMenuCommands.swift:118). There is no keyboard shortcut, and the item is disabled when no project window is focused (:121).
  • A Set Up… button in the main view of an empty project (Views/Library/LibraryView+FilterAndBatch.swift:477; shown only when the project is loaded and empty, App/LibraryWindow.swift:45-52).
  • A Set Up… button in the Project Inspector’s Recipe section (Views/Inspector/Project/ProjectInspector.swift:56,67).
  • A Set Up… button in the Document Inspector, under Info › Recipe (RecipeStepsView.swift:170).
  • Creating a new project opens setup by itself (Models/LibraryManager+Operations.swift:239).

All of these open the same sheet (FirstRunWindow(setUp: true), LibraryWindow.swift:295).

What they see

The sheet. - A sidebar headed “Fichero” lists the steps, and each one can be clicked (FirstRunWindow+Models.swift:32-41, FirstRunWindow.swift:98-101). The steps are: - Purpose - Your Material - What It Is - How It Will Be Done - Start - The footer has three buttons (FirstRunWindow.swift:291-302): - Skip closes setup. - Back is disabled on the first screen. - Continue is the default (Return) button. It reads Start on the last screen.

Screen 1: “What are you doing?” - Subtitle: “Your purpose decides what runs by itself. Every tool stays reachable.” (FirstRunWindow+Recipe.swift:15-16) - The purposes come from the engine (server/recipes/assemble.py:32-42): - Just transcribe - People, places and things - Search my sources - The full knowledge graph - Map places - Edit a corpus - Decipher a script - Not sure yet - A caption under the list reads either “New material goes through these steps by itself.” or “Nothing runs by itself; this purpose’s tools are offered first.” (RecipeSetupFields.swift:37-39).

Screen 2: “Your material” - Subtitle: “How your sources come in, and roughly how much there is. You can add it later.” - Under “How do your sources come in?” there are four choices (RecipeSetupFields.swift:81-93): - Link: Fichero reads the files where they are and never changes the originals. - Copy: Fichero makes its own copy in the project. The originals are never touched. - Move: the files move into the project. The originals are removed from where they were. Choosing it shows an orange warning: “Your original files will be removed from where they are now.” (:98). - Index: Fichero works on the folder in place and writes its changes back into the original files. This is for folders; a single file is linked. - Add a Folder… imports a folder now, the chosen way (:128, RecipeSetupStore.swift:365-373). - A caption reads “Or add material later; it comes in the way chosen above.” (:134) - A field asks “Roughly how many pages” (:142).

Screen 3: “What it is” - Subtitle: “Its languages, scripts and kind. Fichero works out the rest from them.” - Two search fields (RecipeSetupFields.swift:164-168): - Languages: “Name, BCP 47 tag or glottocode, e.g. es” - Scripts: “Name or ISO 15924 code, e.g. Latn” - For each script chosen, Fichero shows what it worked out instead of asking (:247-253): - the writing direction - “Shown in <font>” - where it applies, “May be written in vertical columns: check a page.” - A Material picker offers Handwriting, Print or Typescript.

Screen 4: “How it will be done” - Subtitle: “The steps the rules propose from your answers, and why each is there.” - Each step shows: - its title and layer - a one-sentence explanation - the model’s card - “Needs a model: …” - the reasons the step is there - an Advanced disclosure (RecipeStepsView.swift:46-88) - Pages may leave this Mac is a toggle. It appears only when a cloud model would fit a step; otherwise the screen says “Everything runs on this Mac.” (RecipeSetupFields.swift:54-66). - Also on hand (N) lists the other jobs available (:222). - With no language or no script chosen, the screen says “Add at least one language and one script under What It Is.” (:201).

Screen 5: “Start” - Subtitle: “What will run, on how many pages, and what it costs. Nothing runs before you press Start.” - It shows “N pages · cost”. The cost reads one of: - “free, runs on this Mac” - “price unknown” - a dollar amount - Below that come the workflows and their steps, then “Offered later: …”, then any refusals (RecipeSetupFields.swift:329-347). - Start is disabled while there is a refusal or nothing to run (RecipeSetupStore.swift:146).

Each step’s explanation - The texts come from the topic registry, GET /api/topics (server/api/routes/system/topics.py). - They are written in server/recipes/seed/topics.yaml: job topics from :17, teaching topics from :222. - The app shows the short sentence, then a More disclosure with a paragraph and an example (RecipeStepsView.swift:129-148). - Screen 3 uses the “languages” and “scripts” topics. Each recipe step uses its job’s topic. - Screens 1, 2 and 5 show no topic text.

On Start - The app asks the engine to start the project (POST /api/recipes/project/start). The sheet closes only if the engine accepts (FirstRunWindow.swift:63-64). - The engine records the start in the project’s recipe/started.yaml and queues one run-a-recipe job, which appears in Activity (server/api/routes/system/recipes.py:594-646). - Starting can be undone.

The draft - Continue on screens 1–4 saves the answers and the proposed recipe to the project (recipe/setup.yaml, recipe/recipe.yaml; server/recipes/project.py:19-20). Nothing runs on save, and each save can be undone. - Back and the sidebar do not save.

Adding a language or a layer later (RecipeStepsView.swift:186-265) - Languages field. Placeholder: “Add a language: name, BCP 47 tag or glottocode”. Changing it re-proposes the recipe and saves it. It is in the Document Inspector’s Info › Recipe section only; the Project Inspector does not have it. - Add a Layer… is a menu of the layers the engine says can be added now. It is disabled when there are none. - Remove sits beside each added layer. - After a change, the section shows “For the pages already here: N pages · cost”, the proposed steps, and a Start button. - The Project Inspector shows the layer controls only once the project has a recipe (ProjectInspector.swift:64-66).

Defaults taken, awaiting a ruling

  • Purpose Just transcribe (RecipeSetupStore.swift:28).
  • Material Handwriting (RecipeSetupStore.swift:17,31).
  • Page count 0 (RecipeSetupStore.swift:36).
  • Pages may leave this Mac is off (RecipeSetupStore.swift:37-39).
  • Link as the default way in is ruled (2026-10-03, RecipeSetupFields.swift:73). The other defaults carry no ruling in the code.
  • The language field exists only in the Document Inspector, not the Project Inspector.
  • Not built: a screen for checking models on your own pages. It waits on the evaluation job (FirstRunWindow+Models.swift:20).

Screenshots wanted

The setup screens have no accessibility identifiers. They do have #Previews (RecipeSetupFields.swift:363-398, RecipeStepsView.swift:267-314).

  1. File menu with Set Up Project… highlighted.
  2. Empty project with the Set Up… button.
  3. Setup sheet on screen 1, with the purpose list.
  4. Screen 2 with Move chosen, showing the orange warning.
  5. Screen 3 with a language and a right-to-left script chosen, showing what Fichero worked out.
  6. Screen 4 with one step’s More disclosure open.
  7. Screen 5 with the pages · cost line.
  8. Document Inspector › Info › Recipe, with Add a Layer… open.

2. The Activity window and popover

Spec: specs/ui/activity-and-automatic-work.md. The maintainer’s section will be “What Fichero is doing”.

What a person can do

  • See every run in every open project, opened out into its steps and each step’s pages.
  • Pause, resume or stop a run, a step or a page.
  • Group the rows by project.
  • From the toolbar popover, see at a glance what is running, what is waiting and why, and the state of this Mac.
  • Read in the window’s footer why a project’s activity could not be loaded.

Where it is reached

  • Window › Activity, ⌥⌘0 (FicheroApp.swift:653-666).
  • The activity button in the main window’s toolbar opens the popover (ActivityStatusToolbarItem.swift). The popover ends with Open Activity.
  • Double-clicking a run opens its own Activity Detail window (ActivityMonitorWindow.swift:130-133).

What they see

The toolbar button changes with the state: - idle: tooltip “Background activity — click to view” - working: a spinner, with a count when more than one task runs - an error: a red glyph, tooltip “A background task reported an error — click for details”

The window is one table. Rows open out: run › steps › pages (ActivityMonitorWindow.swift:115,122). Work that belongs to no run, such as an embedding queue, is a row of its own.

Columns (ActivityMonitorWindow.swift:82-110):

Column Shows
Name the name, prefixed “Project · ” when not grouped
State an icon and one word from Running, Waiting, Paused, Failed, Stopped or Done, with a reason when there is one: “Waiting: memory is tight”, “Failed: …”
Progress “12 of 40”, plus “about N left” while running
Started the time it started
Time a live timer
Cost “$0.0023”, “Not priced”, or blank
Errors a red count
Model the model used
(no title) the row’s controls

Every column sorts. The default order puts live rows first, then the newest (ActivityMonitorModel.swift:187-190).

Row controls (ActivityMonitorModel.swift:67-84,167-174): - They are icon buttons named Pause, Resume and Stop. Running or waiting rows offer Pause and Stop; paused rows offer Resume and Stop; finished rows offer nothing. - None asks for confirmation. - A failure shows in the footer as “Couldn’t pause|resume|stop <name>: <cause>“. - Clear Failed is in the toolbar. - Delete is on the right-click menu and the Delete key. It refuses a run that is still running.

Group by Project is a toolbar toggle (ActivityMonitorWindow.swift:64-69). - Tooltip: “Group the rows by project, with this Mac’s own work as a group of its own”. - Off by default, and remembered across launches. - This Mac’s own work is a group titled “This Mac”.

Empty states (ActivityMonitorWindow.swift:44-55): - “No Library Open”: “Open a library to monitor its workflow activity.” - “No Runs Yet”: “Workflow runs from every open library appear here.”

The popover, from top to bottom (ActivityPopoverSummary.swift, ActivityStatusToolbarItem.swift:113-166): 1. “Activity” and the project name. 2. What is running, each with “N of M”, or “Nothing running.” 3. “N waiting” or “N waiting: <reason>“. 4. When it applies, a held-back line, one of: - “Background work is paused. Work you start still runs.” - “Heavy work is held back: <reason>” 5. A This Mac block: - “Memory pressure: normal | warn | critical” - “Heat: nominal | fair | serious | critical” - “On battery” or “On power” - “In use” or “Not in use”

A reading the engine could not take is left out. 6. “Recent errors” (at most three), a CPU line, and Open Activity.

The engine’s reasons for holding heavy work back (server/execution/throttle.py): - “Waiting: memory is tight” - “Waiting: the Mac is hot” - “Waiting: the Mac is on battery” - “Waiting: you’re using the Mac”

“In use” means input in the last 30 seconds.

The footer: why a project was refused (ActivityStore.swift:324-339) - The format is “Couldn’t load activity from <Project>: <cause>“. The cause is one of: - “the engine isn’t allowed to open the project from where it’s saved” - “the engine refused the app’s credentials” - “the engine could not be reached” - the engine’s own message, for any other refusal it names - There is one line per project, with an orange triangle. A line clears when that project next loads. - Since #5468, the app registers its open projects with the engine again on reconnect, so a restarted engine no longer refuses them.

Defaults taken, awaiting a ruling

  • Group by Project is off by default.
  • Pause, Stop, Clear Failed and Delete do not ask for confirmation.
  • The built columns are not the ruled set (2026-10-04). Several things in the spec are not built:
  • the Greenhouse gas, Images run, Steps run, Working on and Started by columns
  • the filters (Now, Waiting, Failed, Done today, All) and search
  • Retry and Show What It Made
  • a detail pane
  • a Pause Background Work toolbar control
  • Defect to check on screen: when the engine gives a reason now, the popover adds it to “Heavy work is held back: ” without removing “Waiting: “, so it can read “Heavy work is held back: Waiting: the Mac is hot” (ActivityPopoverSummary.swift:88).

Screenshots wanted

The identifiers are activity.window, activity.table, activity.row.<id>, activity.group.mac, activity.popover, activity.popover.heldBack and activity.popover.macState.

  1. The Activity window with one run opened out to its steps and pages.
  2. The same window with Group by Project on, showing the “This Mac” group.
  3. A row’s Pause and Stop buttons, hovered.
  4. The popover while work runs, with the This Mac block.
  5. The popover while heavy work is held back.
  6. The window footer naming a refused project.

3. Box colours in Preview, and which pass Preview draws

Spec: specs/source/segment-editor.md, section “Box colour and the segment hierarchy”. The maintainer’s section will be “Editing the layout of a page”.

What a person can do

  • Tell at a glance which lines belong to which region, and in what order they are read.
  • Know which reading of a page the boxes come from.
  • Turn the boxes on or off.

Where it is reached

The Preview’s “what to show” menu (ReaderToolbar.swift:217-253) has: - Show Image - Show Annotations - Show Word Bounding Boxes (the segment boxes) - Show Regions (saved region marks, not segments) - Show Text Inline - Edit Segments

What they see

Colour (Models/RegionColours.swift, SelectionStyle.swift:13-31): - Each region takes a hue in turn, in the order the page is written. There are twelve system colours: blue, orange, green, purple, pink, teal, indigo, brown, mint, cyan, red, yellow. After twelve regions they repeat. - The lines inside a region are shaded along reading order. The first is full strength and the last is lightest, at 45%. - Words and letters take their line’s shade. Region boxes are full strength. - Lines that sit in no region are treated as one region for the whole page. - The colours are system colours, so they follow Light, Dark and Increase Contrast. - In the Inspector’s region rows, each swatch is the colour of the box Preview draws for it (ArtifactPanel+Regions.swift:121,164).

Which pass is drawn (SegmentDisplay.swift:83-102; engine server/models/readings.py:596-659): - A page may hold several passes of segments. Preview draws one, chosen in this order: 1. When the Inspector has an artifact of this document in focus, that artifact’s passes with shapes come first. 2. Next comes the pass the engine marks as drawn: the best-ranked pass that has shapes. 3. Then the rest, in the engine’s rank. - The engine ranks passes in this order, newest first within each tier: 1. a reading someone chose 2. passes a person touched 3. text-layer passes 4. the rest 5. passes passed over - When no pass has shapes, no boxes are drawn. The page’s working pass is still the one whose lines can be picked. - Georeferencing passes are never drawn as boxes.

Defaults taken, awaiting a ruling

  • Shading always follows the as-written order. Choosing another reading order in the Segments pane does not reshade the boxes (SegmentDisplay.swift:164-167).
  • Show Word Bounding Boxes is on by default (#4418), set separately for images and PDFs.
  • Not built: a legend for the colours (source.editor.hierarchy.legend is [GAP]).

Screenshots wanted

  1. A manuscript page with two or more regions, boxes on, showing hue per region and lines fading down each region.
  2. The same page in Dark appearance.
  3. The “what to show” menu (previewWhatToShow) open.
  4. The Inspector’s region rows beside the Preview, showing that the swatches match the boxes.

4. Driving Fichero from outside

Spec: specs/harness/surfaces-from-openapi.md. The maintainer’s section will be “Driving Fichero from outside” (MCP, AppleScript, Shortcuts).

What a person can do

  • Connect an AI agent to Fichero through its MCP server.
  • Script the app with AppleScript.
  • Build Shortcuts from Fichero’s actions.

The MCP server

What it is. - The server lives in fichero-mcp/. It runs over stdio as fichero-mcp (fichero-mcp/pyproject.toml:39). To add it to Claude Code: claude mcp add fichero -- fichero-mcp (fichero-mcp/README.md:29). - It talks to the running app’s engine, at http://127.0.0.1:8765 unless --api-url or FICHERO_API_URL says otherwise. - There is no Settings pane for it. Settings › MCP manages other MCP servers.

Where the tools come from. - Every tool is generated from the engine’s API contract, one tool per operation (event streams excepted), by fichero-server/scripts/generate_openapi_mcp.py into openapi_tools_generated.py. - At this commit there are 832 tools. - Tool names read fichero_<tag>_<action>, for example fichero_recipes_start_project. - Each tool’s description names its route and whether it reads or changes data. - A guard, scripts/check_mcp_generated_current.py, fails when the committed tools differ from what the contract would generate. Tools cannot drift from the API.

Toolsets. - A toolset is one tag of the contract. - By default the server offers the recipe golden path (server.py:50): recipes, training, check, segments, documents, activity, local-models, hpc. - --toolsets a,b picks others, and --toolsets all gives every one. An unknown name is refused with the list of known ones (server.py:169-178). - A few older tool names stay available whatever is chosen: fichero_health, fichero_use_library, fichero_activity, fichero_search and the like.

The full list of toolsets is in the generated module’s TAGS:

actions, activity, agent-memory, annotations, artifacts, auth, authz, batches, bibliography, bookmarks, campaigns, canvas, chains, chat, check, citation-rendering, citation-usages, citations, claim-curation, claim-links, claims, classifications, content-representations, conversion, documents, editorial, engine, entities, evaluation, export, folders, fonts, formats, georeference, hands, hpc, iiif, images, ingest, integrations, knowledge-graph, letterforms, library, library-items, library-links, library-sync, links, local-inference, local-models, locations, mcp, mcp-servers, migrations, model-comparison, models, multilingual, notes, orchestration, pairing, projects, providers, reading-at-scale, reading-orders, recipes, references, registries, renditions, research, rights, sandbox, schedules, search, search-explanation, segments, settings, signs, source-settings, sources, storage, sync-folders, tasks, topics, training, triggers, users, views, workflow-execution, workflows

Plus ui, which is not part of the contract.

--toolsets ui adds the UI verbs (ui_control.py:151-162): - fichero_ui_open_project - fichero_ui_open_node - fichero_ui_select_nodes - fichero_ui_reveal_segments - fichero_ui_show_pane - fichero_ui_show_inspector_tab - fichero_ui_screenshot

Each drives the app through AppleScript, so they work on a Mac only.

Agents act as their own account. - Tools that change data run as the “agent” account when that account has a stored session (server.py:123-160). Its changes are then recorded as the agent’s. - Without a stored session, they run with the owner’s credential, recorded as coming from fichero-mcp. - The agent signs in with fichero auth login agent.

AppleScript

From fichero/fichero/Fichero.sdef, “Fichero Suite”:

Command Takes
open project a path
open node an id
select nodes a list of ids
reveal segments segment ids, in page a page id
show pane library, preview, reader, inspector, activity, chat or segments
show inspector tab Content, Artifacts, Annotations, Notes, Interpretation, Entities, Knowledge Graph, Citations, Related, Edits or Info
screenshot a PNG path, optionally of pane

Older commands remain: run workflow, stop run, get workflow status, pause workflow, resume workflow, run chain, list workflows, list documents, search documents, import file, get document info.

Shortcuts

UI actions (Intents/FicheroUIVerbIntents.swift): - Open Project - Open Node - Select Nodes - Reveal Lines in Preview - Show Pane - Show Inspector Tab - Take Screenshot

Other actions: Merge Entities, Create Note, Delete Document, Run Workflow, Create Annotation.

Ten of them are offered as ready-made App Shortcuts (FicheroShortcuts.swift:35-66), among them “Open Item” and “Reveal Line”. Select Nodes and Show Inspector Tab are actions only, because Apple allows ten.

One path

AppleScript, Shortcuts and the MCP ui tools all call the same in-app verbs (Intents/UIVerbs.swift:4-8). None of them has a second way of doing the same thing.

Defaults taken, awaiting a ruling

  • The default toolsets are the recipe golden path. ui is off unless asked for.
  • No Settings pane starts or configures fichero-mcp.
  • fichero-mcp/README.md still says “~29 tools”. This is a contributor-docs fix, not the maintainer’s.

Screenshots wanted

None in the app; this is a terminal and editor story. Optional:

  1. Shortcuts with Fichero’s actions listed.
  2. Script Editor showing Fichero’s dictionary.

5. Training data quality: the line check, the set preview, the evaluation job

Specs: - specs/source/models-chains-and-projects.md (source.lines.reading-checked-against-the-page) - specs/compute/jobs-and-fine-tuning.md (compute.tune.set-excludes-flagged-lines) - specs/compute/distillation.md (distill.eval.*)

The maintainer’s section will be “Making your own model”.

None of this has a screen in the app yet. It is reached through the API and the MCP tools only (scripts/check_endpoint_coverage_matrix_known_gaps.json:283-294).

What a person (or their agent) can do

  • Check a teacher model’s line readings against the page before training on them.
  • See exactly what a training set will hold, and what it leaves out, before sending anything.
  • Score readers on pages they were not trained on, and keep the scores on each model’s card.

The line check

server/checking/line_check.py. The check is called line-against-page, and its job is “Check lines against the page”.

How it works. - Kraken reads each line again on that line’s own baseline, giving a rough read. - The teacher’s reading is scored against that rough read, and against the rough reads of up to two lines either side in the same column. - The score is 1 − CER, ignoring accents.

A line is flagged (:38-44,73-78): - “closer to a neighbour”: a neighbouring line’s rough read agrees with it at 0.40 or more, and by at least 0.15 more than its own line does. This is the shifted-line case. - “below the threshold”: otherwise, when it agrees with its own line under 0.30.

What follows a flag. - The line gets a reject verdict from a model. Its reasons give both scores and the neighbour’s rough read. - Lines a person has checked are skipped. - Empty readings are counted as not scored. - The job’s summary reads “N passed, N closer to a neighbour, N below the threshold”.

MCP tools. - fichero_check_start_run with check: "line-against-page", layer readings, provider kraken - fichero_check_run_status - fichero_check_list_verdicts - fichero_check_cancel_run

Flagged lines leave the training set

server/training/kraken_set.py:147-245. - A Kraken training set leaves out lines that are: - empty - null - rejected (their newest verdict is a reject, which is what the line check gives) - The set’s manifest counts what was left out, by reason, lists those lines, and says whether a check ran.

The set preview

  • MCP tool: fichero_training_preview_set (GET /api/training/set), given the teacher, the pages, and the held-out pages.
  • It shows:
  • pages and lines
  • lines left out, by reason, and which ones
  • whether a check ran
  • the held-out pages
  • anything missing
  • It writes nothing and sends nothing.

The evaluation job

server/training/evaluation.py. The job is “Evaluate models on held-out pages”.

What it does. - Each candidate reads the lines of the pages’ checked pass. By default the readers this Mac already has are added for comparison. - Every page is scored with Fichero’s one CER function, under four policies: diplomatic, layout-insensitive, lenient, accent-blind. - Models are ranked by layout-insensitive CER. - Only models on this Mac can be evaluated; remote ones are refused.

Held-out pages. - With no pages named, the job uses the pages every trained candidate lists as held out on its card. - It refuses, saying why, when a trained model has no held-out pages, or when no page is fair to all the candidates.

Results. - Each run is added to the model card’s evaluations, never replacing an earlier one. - A run records: when it was measured, the pages, the scores per policy, the scores per page, and what it was compared with.

MCP tools. - fichero_evaluation_start - fichero_evaluation_status - fichero_evaluation_model_scores

Defaults taken, awaiting a ruling

  • The thresholds: two neighbours, a 0.15 margin, a 0.40 floor, 0.30 low. They come from the Sergio project’s own check, which found Mosquera’s shifted lines (2026-10-04). No ruling in the code calls them final.
  • The check scores ignoring accents. Evaluation ranks by layout-insensitive CER.
  • Evaluation adds the out-of-the-box readers by default.
  • Not built:
  • a flagged line shown as flagged in the app
  • the model’s Test action and its training card (#5439)
  • a check review surface
  • The spec names the check tools fichero_check_run / _status / _verdicts (models-chains-and-projects.md:67). The generated names are the ones listed above.

Screenshots wanted

None until the app surfaces exist. Until then, the manual can show a transcript of an agent running fichero_check_start_run and fichero_evaluation_model_scores.