Source material → candidate ltp.yaml

Where this skill lives

This repository (life-itself/reasoncommons, skills/ltp-project/) is the home of this skill. Edit it here. The Reason Commons app repository (Promise-Foundation/reason-commons) may still carry an older copy under .claude/skills/ltp-project/; that copy is stale, and nothing should be copied from it over this one.

TODO — no validator. This skill no longer requires a Reason Commons app checkout: the bun run check:import step was dropped because it never worked reliably for people without the app repo (see the bead "ltp-project: validate without an app checkout"). Restore validation in a form that runs standalone (for example a self-contained script in scripts/), then delete this note.

The format is the app's own. What this skill writes is what the app imports through its attach control, and what the app exports from a space (Integrations → Export reasoning) as canonical JSON or as the YAML dialect, with the version series and event history under history. A space's export committed to a connected repository — .reason-commons/<space-id>.ltp.json — is therefore a live, complete example of the format. Do not hand-write anything that format already carries for you.

What you produce

Two files. Never one.

reports/ltp/<slug>/<slug>.ltp.yaml     the candidate
reports/ltp/<slug>/<slug>.report.md    everything the YAML cannot hold

The file is not machine-validated here (see the TODO above), so hold it to references/example-project.ltp.yaml and references/vocabulary.md by hand and say in the report that it is unvalidated.

To inspect the candidate in the repository's read-only dashboard, run:

python3 skills/ltp-project/scripts/preview_dashboard.py reports/ltp/<slug>/<slug>.ltp.yaml

The preview opens a local browser page and serves a temporary dashboard-compatible view; it does not modify the candidate or import it into a Reason Commons space. For a standalone HTML export, use $ltp-visualize or add --export-html to the command. The preview requires PyYAML (python3 -m pip install pyyaml). See references/preview.md for format limitations and options.

In the app repository reports/ is gitignored, which is correct: a machine wrote this and a person has to read it before any of it is ratified. In another repository, write to a path a person will review before it is committed, and say which one. Use a different path only if asked.

Read these first

  • references/example-project.ltp.yaml — the format in full, correct, across all six views. Copy its style. It is the same file the app ships as public/example-project.ltp.yaml, and a unit test holds the two identical.
  • references/vocabulary.md — the only valid view names, roles, relationship kinds and assessment kinds. Never write one of these from memory.

Then, as you need them: references/extraction.md (reading, segmenting, propositions, identifiers, a worked example), references/validation.md (each code, its cause, its repair), references/report.md (the report's shape).

Do not take view names from the spec

LTP_RATIFICATION_AND_IMPORT_SPEC.md §19.2 lists the views as goal | problem | conflict | solution | implementation | transition. Those are the interface's names. A file using them is refused. The six values a file uses:

goal   current_reality   conflict   future_reality   prerequisite   transition

Procedure

  1. Size the source. For a PDF: ls -l, and mdls -name kMDItemNumberOfPages -raw <pdf> for a page count. For a repository or a folder: list it and decide which files state something about the system — plans, READMEs, decision records, issues, notes. Code is evidence of behaviour, not of intent; it belongs in the report's coverage note, not in propositions.
  2. Read it. A PDF in windows of at most 20 pages with Read's pages parameter; a text source whole. Keep an extraction ledger as you go — locator | verbatim fragment | first-guess view — and write it to a scratch file for anything over about 60 pages or a dozen documents.
  3. Note the reading conditions. Empty or mangled text from a PDF means the page is a scan being read as an image. Record it, mark those items low confidence, and say that anthropic-skills:pdf can OCR a text layer first. Never proceed silently.
  4. Segment. Keep only sentences that assert something about the system. Drop headings, page furniture, bare captions, scope notes, and any sentence whose subject is the document rather than the world.
  5. Rewrite each as a complete proposition. Present tense, one named subject, one claim, the source's quantity and hedging preserved, no it or this. Never supply a subject the source lacks — that sentence is not a proposition.
  6. Put each in exactly one view. Wants something true, or a condition for it → goal. Happening now and unwanted, or a cause of it → current_reality. Two things pulling against each other → conflict. A change to make, or an effect expected once made → future_reality. Something blocking a change, or a step past the block → prerequisite. The before and after of a change, or an action in sequence → transition. Still ambiguous → the view the section is about, and record the call in the report.
  7. Assign a role that view holds. From references/vocabulary.md only. When unsure use observation — it is valid in all six views and is how you keep a file honest instead of precise-sounding.
  8. Relationships, conservatively. Default is no relationship. See below.
  9. Assumptions. One per relationship, only where the source names the belief the link rests on. Zero is a fine answer.
  10. Assessments. Only where the source itself draws the conclusion. Default is none.
  11. Provenance on every entity — provenance: { path: "<locator>" }, where the locator is <pdf>#page=<n> for a PDF, <path>#L<line> for a text file, and the issue or comment URL for a tracker item. This becomes the locator in the import plan and in every refusal message about that proposition, so make it one a person can act on.
  12. Write both files, then check them by hand. There is no validator to run (see the TODO above). Re-read the YAML against the three rules below and references/vocabulary.md: every view, role, relationship kind and assessment kind valid; every identifier unique; every relationship inside one view; every reference resolving. In the report's "Validator output" section write "Not machine-validated", and tell the person to attach the file in the Reason Commons app, whose import runs the full analysis and reports what it refuses.

Nothing has to be listed in dependency order. The importer resolves references in two passes and plans in its own order, so a child may name a parent defined later.

A plan, a backlog or an issue export

Each task is a candidate transition action, and only a candidate. Its "why" section is the transition_need; a "current state" or "context" section is the transition_existing_reality; acceptance criteria that describe something observable in the world once the work is done are the transition_expected_effect. Criteria that only say when the work is complete are not an effect and go in the report. A task that traces to no goal or need in the material is recorded in the report as untraced, never given a reason it does not have. Ordering words ("after", "blocked by", "first") are precedes.

Relationships: the burden of proof

Emit a relationship only when a single sentence in the source asserts the link, unhedged, between two propositions already extracted into the same view. Everything weaker goes in the report.

in the sourcewhat you may write
"X because Y", "Y therefore X", "X is driven by Y"causes
"one factor is", "partly explains", "among the drivers"contributes_to, never causes
"may cause", "might lead to", "could result in"nothing; a judgment call
"is associated with", "correlates with"nothing; correlation is not a causal claim
"we believe", "it appears", "suggests", "is consistent with"nothing; the belief may become an assumption on a link you did assert
"A and B together cause C"pick the dominant cause or omit; record the joint claim

Default kinds per view: goal → necessary_for; current_reality → causes or contributes_to; conflict → conflicts_with; future_reality → causes; prerequisite → overcomes, necessary_for; transition → precedes, produces.

Three rules never traded away

  1. One flat identifier namespace across entities, designations, relationships, assumptions and assessments. Use <view>-<kind>-<slug>: g-e-ship-same-day, g-d-ship-same-day, r-rel-batch-causes-wait.
  2. Exactly one identifier in from_entity_ids, and never logic.mode of compound_and or alternative_or. Joint causes are refused outright.
  3. A relationship joins two propositions in the same view. from, to and the relationship's own tree must all match. No exceptions, including for the kinds documented elsewhere as cross-tree. Such a link is real reasoning the format cannot carry — record it, do not force it.

Stop and ask when

  • a PDF has no text layer and the page images are illegible
  • the source is not about a system anyone acts on — a novel, a price list, a form, or code with no plan, README or issue that says what it is for
  • the material is about several unrelated systems, and it is not clear which one the project is meant to be

When the question is a choice among options you can name, such as which of the systems you found the project should cover, ask it with the host's native interactive question or selection tool if it has one (AskUserQuestion in Claude Code), with each candidate as an option and a one-line description of it. Otherwise list the options in plain text and ask for a reply. Ask open-ended questions in plain text.

Never

  • invent a proposition to satisfy a dangling reference
  • delete real content to make the file look valid
  • write vision or higher_level_objective — the file contract accepts them and no view holds them
  • assess on the author's behalf, when the source only recommends
  • hand over the YAML without the report
Built with LogoFlowershow