# configuration/strings/plan.fragment.strings.ts

> 83 lines of code and 4 definitions.

Tree: Site tree
Language: typescript
Layer: product
Canonical: https://banes-lab.com/anatomy/tree#file-configuration-strings-plan-fragment-strings-ts
Source text: https://banes-lab.com/assets/sources/source.d94226ae3cc5fe3b26abff4848544718da317dbb79eb5f0a1352afeefc5b19f3.generated.txt

## Definitions

- `QUESTION_DIAGRAM` (lexical_declaration, line 5)
- `TENSION_DIAGRAM` (lexical_declaration, line 8)
- `QUESTION_SECTION` (lexical_declaration, line 11, exported)
- `TENSION_SECTION` (lexical_declaration, line 52, exported)

## Source

```typescript
import { QUESTION_SECTION_ICON, TENSION_SECTION_ICON } from "#configuration/icons/plan.icons";
import { QUESTION_SECTION_ID, TENSION_SECTION_ID } from "#core/ids/plan.ids";
import type { Section } from "#types/document.types";

const QUESTION_DIAGRAM =
    'flowchart TB\n    appears["An uncertainty appears"]\n    changes{"Does the answer change what gets built?"}\n    contract{"Does the contract already decide it?"}\n    seat{"Is there a channel to ask?"}\n    ask["Ask now, with a recommendation first"]\n    state["State the assumption, name what would settle it, return"]\n    shared["Do the parts every answer shares"]\n    proceed["Return a result, no question"]\n    assume["Assume, and the work rests on a guess"]\n    appears --> changes\n    changes -- no --> proceed\n    changes -- yes --> contract\n    contract -- yes --> proceed\n    contract -- no --> seat\n    seat -- yes --> ask --> shared\n    seat -- no, a bounded run --> state\n    changes -. skipped .-> assume';

const TENSION_DIAGRAM =
    'flowchart LR\n    a["Rule A"]\n    b["Rule B"]\n    line["One line of code"]\n    boundary["The domain boundary"]\n    form["The one form that satisfies both"]\n    off["One rule switched off"]\n    a --> line\n    b --> line\n    line --> boundary\n    boundary --> form\n    line -. the tempting move .-> off';

export const QUESTION_SECTION: Section = {
    icon: QUESTION_SECTION_ICON,
    id: QUESTION_SECTION_ID,
    intro: "You decide what the work is for, as described in worth before work, while the shape of the work is left to the model. When a question crosses from the model's side to yours, the model is asked to raise it at the point where it appears, before any work that depends on it, because a decision the model makes without asking is an assumption. <cite>three fates</cite> shows where an uncertainty can go.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the model is asked to raise an uncertainty as soon as it would change what gets built, with a recommendation placed first and its reasoning given, and with the other options as real alternatives whose cost is stated. While the answer is pending, the model is asked to do the parts that do not depend on it. When the model runs as a bounded agent with no channel back to you, it is asked instead to state the uncertainty and the assumption it took, name what would settle it, and return it as one of the handoff signals typed on the grammar page.",
                    boundary:
                        "A bounded task with a clear contract returns a result rather than a question, since questions are for decisions that belong to you, not for ones the contract has already made. A question about what the project is for is almost always yours, while a question about how something should be shaped rarely is.",
                    cause: "Asking feels like slowing down, and the model and the developer both tend to prefer momentum to a pause.",
                    decision:
                        "The cost of the pause is paid at the uncertainty, rather than the cost of the rework after it.",
                    failureMode:
                        "The model guesses the missing decision, builds a day of work on the guess, and mentions the guess in a footnote at the end.",
                    kind: "lesson",
                    principle:
                        "For this reason the model is asked to raise a question where it appears, and to state an assumption where it makes one.",
                    problem:
                        "A question that is never asked turns into an assumption, and the work then rests on a decision that neither you nor the model made on purpose, which the ontology calls unowned risk.",
                    validation:
                        "To check this, look at the questions the model raised in a session and where in the work each one landed. A question that arrived after the work depending on it was an assumption reported late.",
                },
                {
                    kind: "text",
                    text: "Questions go through the harness's question tool, which has a fixed shape, and a question that does not go through the tool is treated as not asked. The reason is practical: a question in chat prose is easy to scroll past, while the tool presents it as a decision you can take in one read. Each call carries only a few questions, each with options you can hold in mind at once. The first option is the recommendation, and its description gives the reasoning as well as the choice. The other options are genuine alternatives that say what happens if chosen, including the cost. <em>It depends</em> does not count as an answer, and a weak recommendation is marked as weak, together with what would make it stronger.",
                },
                {
                    kind: "text",
                    text: "The same uncertainty reads differently depending on when it is raised. Asked late, it reads <em>done, note that I assumed the second shape, let me know if you wanted the first</em>. Asked where it appears, it reads <em>two shapes fit here, I recommend the second because the first needs a second config, which one, and meanwhile I am doing the parts both share</em>. The first leaves you a day of work to undo, while the second leaves you a decision to make.",
                },
                { caption: "three fates", kind: "mermaid", text: QUESTION_DIAGRAM },
            ],
            title: "The pause, not the rework",
        },
    ],
    title: "Ask where it appears",
};

export const TENSION_SECTION: Section = {
    icon: TENSION_SECTION_ICON,
    id: TENSION_SECTION_ID,
    intro: "Sometimes two rules meet on one line of code and disagree. This method treats that as a boundary between two domains rather than as an exception, and the collision has one resolution, as shown in <cite>one form</cite>.",
    subsections: [
        {
            blocks: [
                {
                    application:
                        "In practice, the first step is to find the domain each rule serves, and the second is to find the form that satisfies both. The resolution is recorded once, at the place where the next collision of the same kind will be met, and one rule is never satisfied by breaking the other.",
                    cause: "Two rules that collide come from two different domains, and the collision marks the line between them.",
                    decision: "A tension is resolved in the architecture rather than by disabling one of the rules.",
                    failureMode:
                        "A rule is turned off for one file so that another rule can pass, and that file becomes the place where neither rule means anything any more.",
                    kind: "lesson",
                    principle:
                        "For this reason, when two enforced rules apply to the same code, I look for the one form that satisfies both, and where the rules hold in different scopes, that form is the boundary between the scopes.",
                    problem: "When two rules conflict, the tempting move is to switch one of them off.",
                    validation:
                        "To check this, search for every rule that you or the model switched off. Each one is either a resolved tension with its resolution written down, or an unresolved tension that is still hidden.",
                },
                {
                    kind: "text",
                    text: "Two collisions from this site's own code show how this works. In the first, a rule that bans literal file paths meets a declaration file that has to spell out its own paths. The boundary lies between declaring a path and using one, and the one form is that the declaration file is the single exempt place while every consumer reads the path from it by key. In the second, a rule that every export needs a consumer meets a registry entry that has no consumer until a variant registers itself. The boundary lies between a capability and its use, and the one form is that the registry pattern resolves variants by auto-discovery, so the variant file is the consumer.",
                },
                {
                    kind: "text",
                    text: "The architecture page describes three ways to handle a tension, separating, trading or mitigating, and its principle a tension has a mechanism decides when a boundary is the answer and when a measured trade-off is. Both rules are right inside their own bounded context, and the line of code sits where the two contexts touch, which is why explicit boundaries are the first thing to name. Once the boundary is named, the answer carries over: the next collision on the same boundary has the same answer, while a collision on a different boundary is a different tension rather than a precedent.",
                },
                { caption: "one form", kind: "mermaid", text: TENSION_DIAGRAM },
            ],
            title: "A tension is a boundary",
        },
    ],
    title: "When rules collide",
};
```
