Folio Assistant Core

discussion — settling what an agent cannot read off disk

An agent that has just read bootstrap's README.md knows the shape of a harness and nothing about this one. Two questions have no answer in any file it can reach:

No instruction body produces those. They are judgements held by whoever asked for the harness, and the only way to obtain one is to ask. This skill is what that asking must produce. How to ask is not particular to this question: processes/discussion.bpmn narrows the candidates and then calls human-agent-discussion, the one reusable way bootstrap asks a person anything, with no default allowed.

What a skill is, and where the tool comes in

A skill declares an input schema and an output schema. The actor applies judgement to take action in a task, using tools, and the declared outputs are generated by those tools while performing the task, in the context of a given process.

Each clause does work here:

clausein this skill
input schemadiscussion.input.schema.json — what is known before asking
judgementwhich question to put, to whom, and when one answer is enough
using toolsthe discuss tool: put a question to a participant, receive an answer
output schemadiscussion.output.schema.json — the harness and repositories, determined
in a processalways inside one: the process's task points at this skill, never the reverse

The distinction the table makes is the one worth holding: the tool does not decide. It carries a question out and an answer back. Judgement chooses what to ask and rules on when the answer settles the matter. An agent that treats the tool as the decision has skipped the skill.

And the output schema is why this is a skill rather than a conversation: the task is not finished when a pleasant exchange has occurred, it is finished when a document conforming to discussion.output.schema.json exists. That is checkable; "we discussed it" is not.

The participants are symmetric

Both directions are the same skill:

The output records who answered (kind: person | agent), because an answer from a sibling agent is evidence of a different weight from an answer by the person who wants the harness. Neither is refused; they are not conflated.

First, say where you are

Before narrowing anything (processes/discussion.bpmn, A_DetermineWhere), the Bootstrapping Agent determines the three things human-agent-discussion requires before any question (owner, 2026-10-01):

They go into the called discussion with the candidates. One that cannot be determined is never filled with a default: it is asked about first, and the harness question waits.

Rules

Ask the fewest questions that settle it. The Bootstrapping Agent's persona is "asks exactly one question when it must". Narrow the candidate list from context first (a repository whose root already holds a declaration, <name>.json, is not a blank slate) and put the residue as one question with the candidates named. A question a reader must go and research is not ready.

Never infer the answer from a default. If nothing is known, the output's determinedBy is asked, not assumed. assumed is permitted exactly once, for the case the README already states, and it must carry the reason.

Record repositories as pairs, not as a list. read from and written to can be the same repository or two; a flat list loses which is which, and the whole point of determining them is to know where the declaration lands.

A refusal is an outcome. If the participant declines to settle it, that is outcome: "unsettled" with what was asked and what is still open — not a guess, and not an error. The process has an end for it.

Inputs and outputs

Both sit in schemas/, beside graph.schema.json, and are plain JSON Schema. That is deliberate: a Bootstrapping Agent has no MCP server and no validator, so the contract has to be something it can read, not something it must call.

Why this is in bootstrap at all

bootstrap/ is meant to be as small as it can be, so anything in it has to earn its place against that.

The owner's rule for the neighbouring case is worth stating exactly, because half of it decides nothing and the whole of it decides everything:

logging is optional, unless indicated on tasks.

log-message is in bootstrap/ for precisely that reason — bootstrap's own tasks indicate it, and drawing the call is how a task says so. "Optional" is a property of the blanket feature, not of a step whose instructions require it.

discussion earns its place on a different footing, and a narrower one: an agent that cannot determine which harness and which repositories are involved cannot take the first step of installing a harness at all, and no amount of reading will supply it. Not indicated by a task — presupposed by every one of them.