Agent workflow

Before any of the workflows below, the human prepares the matching harness instructions so the agent starts with the correct mode contract:

booktx agents write . --mode isolated --profile PROFILE   # then cd translations/<profile>
booktx agents write . --mode collaborative                 # stay at the project root

The agent then starts in the matching directory and runs booktx mode . and booktx doctor isolation . to confirm the mode. The generated AGENTS.md is the local entry contract; it does not replace the installed booktx skill.

1. Choose the access mode

Collaborative translation workflow

Start at the project root when you need profile selection or cross-profile review:

booktx status .
booktx profile list .

If multiple profiles exist, pass --profile on all translation-state commands.

Before starting isolated translation, run the generic source-policy interview when source analysis is available:

booktx source analyze BOOK --write --sync-profiles
booktx source interview-plan BOOK --profile PROFILE --write
booktx source interview-next BOOK --profile PROFILE --format markdown
booktx source interview-status BOOK --profile PROFILE --fail-if-open

Persist only user-approved answers with booktx source interview-answer BOOK CAND-... --profile PROFILE --target TARGET --write, or record explicit skips with booktx source interview-skip.

Isolated evaluation workflow

Start inside translations/<profile>/ when you want unbiased model or context evaluation for one profile:

booktx mode .
booktx doctor isolation .
booktx source status .
booktx context status .

In isolated mode, use only profile-local booktx ... . commands. Never use parent paths, absolute paths, shell globs, interpreter snippets, or sibling profile commands. If booktx prints a sibling profile or a parent path, stop and report a booktx isolation bug.

2. Read the profile-local context

context.md

Do not start translating when context.json is missing or not ready.

3. Request a task

booktx translate next . --unit batch --max-words 800 --format block

This writes:

  • tasks/TASK.source.block.txt

  • ingest/TASK.block.txt

  • ingest/TASK.json

The task JSON also records the dotted baseline version plus the immutable context-view snapshot used for that task.

4. Fill the durable ingest file

Translate only the record bodies. Keep record ids and placeholders unchanged.

5. Submit the result

booktx translate insert . \
  --task-id TASK \
  --file ingest/TASK.block.txt \
  --format block

6. Validate and build

booktx validate . --fail-on-warnings
booktx build . --require-complete

For per-batch validation within a bounded todo, use scoped booktx check . --chapter CHAPTER --fail-on-warnings instead. Use booktx validate only for the final pre-build check.

6b. Refresh editor QA indexes

After translation/review changes, refresh the three editor-friendly indexes for source-only search, target-only search, and side-by-side review:

booktx translate export-index .

This writes source-index.json, target-index.json, and source-target-index.json into the profile directory. Use rg to search translated terms without English source false positives (rg "Wespen" target-index.json) or source terms without target matches (rg "Wasp" source-index.json). Use nvim source-target-index.json for side-by-side scanning.

The three files are generated artifacts. Do not edit them manually and do not use them as build input.

7. Longer bounded runs

When the user asks to continue for multiple chapters, do not request one huge chapter task. Create a todo instead:

booktx translate todo-next . --profile PROFILE_A --chapters 3 --batch-words 800 --write
booktx translate todo-status . --profile PROFILE_A --latest
booktx translate todo-resume . --profile PROFILE_A --latest --format block

Read the generated todo markdown and follow its loop. After each completed chapter, fill the booktx context chapter-note template printed by booktx translate insert; do not hand-edit context.md for chapter notes.

If validation flags an old accepted record during a bounded run, use booktx translation revise-record . RECORD_ID --target "..." to fix it. Never edit translation-store.json directly. That chapter-note append affects the next task’s context view, but it does not mint a new dotted version by itself. Stop when the todo goal is complete, when todo-status says it is complete, or when a stop condition occurs. Report partial progress if conversation or tool budget runs low. --max-run-words is advisory only.

Guardrails

  • Never mix files between profiles.

  • Cross-profile reference work is allowed only from project-root collaborative mode.

  • Use booktx context sync for same-book sibling policy propagation instead of copying context files or hand-repeating glossary decisions.

  • Never edit .booktx/chunks/*.json directly during normal translation work.

  • Never edit translations/<profile>/translation-store.json directly. If validation flags an old accepted record, use booktx translation revise-record to fix it.

  • Never edit translations/<profile>/translated/*.json directly; use booktx translate export.

  • Use booktx profile compare for cross-profile review instead of mixing store files manually.

  • Use project-root mode to create or refresh a judge source snapshot. After booktx judge sync-sources or booktx judge prepare-isolation, a selection profile may run booktx judge status/next/record/insert from its profile root without sibling profile access.

  • If a todo-status, todo-resume, or todo-next command fails with an internal booktx error, stop and report the tool failure. Do not silently switch to a large unbounded translate next --unit chapter task. Bounded todos exist to keep agent runs within budget; bypassing them defeats that purpose. Only use translate next --unit chapter for small chapters or when the user explicitly requests a whole-chapter task.

Finish a single large chapter

If the user asks to finish a chapter and that chapter has more than the safe task budget, booktx automatically creates a single-chapter todo and returns bounded batch tasks. Do not create a giant chapter task:

booktx translate next . --chapter 0005 --unit chapter --max-words 800 --format block
# booktx auto-creates a single-chapter todo and returns a bounded batch
booktx translate insert . --task-id TASK --file ingest/TASK.block.txt --format block
booktx check . --chapter 0005 --fail-on-warnings
booktx translate todo-resume . --latest --format block
# repeat until chapter complete

Only use --force-chapter for small chapters or when explicitly requested.

After each chapter, always run booktx check before adding the chapter note:

booktx check . --chapter 0005 --fail-on-warnings
booktx context chapter-note . 0005 --title "ONE" ...

Context approval hard stop

Stop and ask the user whenever context questions are open or only recommended. Do not translate from a context that you generated yourself. Prepare a user review form, then wait for explicit approval or edited answers before running booktx context approve and booktx context mark-ready.

EPUB inline XHTML translation rule

For EPUB records, preserve inline XHTML tags and attributes in the target. Translate text nodes only. Do not convert <em> or other inline tags to Markdown markers.

7b. Quality review pass workflow

After validation passes, optional quality review improves the accepted target:

  1. booktx review status . – check which records still need review per pass

  2. booktx review next . --pass 1 – create a review task for un-reviewed records

  3. Edit the prefilled ingest block under translations/<profile>/reviews/

  4. booktx review insert . --review-task-id TASK --file reviews/TASK.block.txt

  5. Repeat for pass 2: booktx review next . --pass 2, review, insert

  6. Validate and build: booktx validate . --fail-on-warnings && booktx build . --require-complete --require-reviewed

During review pass tasks, review the existing target critically. Preserve meaning, placeholders, protected terms, and inline XHTML. If the current target is already good, submit it unchanged – booktx stores an explicit review candidate either way.

Judge / selection workflow

When the user wants to assemble a best-of profile from several sibling translations, stay at the project root and use the dedicated judge workflow:

booktx judge create-profile ./book JUDGE_PROFILE \
  --target de \
  --target-locale de-DE \
  --sources PROFILE_A,PROFILE_B \
  --context-from PROFILE_A \
  --model gpt-5.5 \

booktx judge accept-identical ./book \
  --profile JUDGE_PROFILE \
  --sources PROFILE_A,PROFILE_B \
  --unit chapter \
  --chapter 0001 \
  --max-records 100 \
  --write

booktx judge next ./book \
  --profile JUDGE_PROFILE \
  --sources PROFILE_A,PROFILE_B \
  --unit chapter \
  --chapter 0001 \
  --max-records 8 \
  --format decisions

Judge tasks expose the original source plus each source profile’s effective candidate. Prefer exact candidate copy when one option is already correct. For decision_kind: copy, set selected and reason and leave TARGET empty so booktx copies the selected candidate exactly. Choose decision_kind: edited only when every available candidate needs a repair. Submit the completed judge ingest file with booktx judge insert ...; store and records provenance in translation-selection-ledger.json.

In selection.purpose=compare (the default, shown above), prefer accept-identical and sweep-identical for true multi-source identical candidates.

In selection.purpose=revise, never use deterministic selection commands. Create the profile with --purpose revise and exactly one source; every record requires an explicit copy or edited judge decision. Later corrections must use booktx judge record . --record RECORD_ID, not translation or review revision commands, because revision output is valid only while each active target has matching judge-decision provenance. See Single-source judge revision profiles in docs/profiles.md.

Isolated judge workflow

After the selection profile context is ready, prepare a profile-local snapshot of the source candidate stores:

booktx judge prepare-isolation ./book --profile JUDGE_PROFILE --write

This copies source translation-store.json, translation-version-ledger.json, identity.json, and profile-config.json into an immutable judge-sources/snapshots/<SNAPSHOT_ID>/ directory and writes judge-specific AGENTS.md instructions. Then start the judge agent inside the profile root:

cd translations/JUDGE_PROFILE

# profile root
booktx judge status .
booktx judge accept-identical . --unit chapter --chapter 0001 --max-records 100 --write
booktx judge next . --unit chapter --chapter 0001 --max-records 8 --format decisions
booktx judge insert . --judge-task-id TASK --file judge-ingest/TASK.decisions.txt --format decisions
booktx judge reset-ingest . --judge-task-id TASK --format decisions --write
booktx judge continue . --max-records 8

The isolated judge workflow uses copied candidate data and never reads sibling profiles. Output is sanitized: no --profile flag, no parent paths, and no translations/<profile> references. Submission paths are confined to regular files inside the current profile. Do not chain judge insert and judge next in one shell command; continue only after a successful insert.