{# The plan. Every requirement is shown WITH its source quote: that pairing is the anti-fabrication mitigation, so a reviewer reads the claim and its evidence side by side. Nothing here is marked safe — a quote is text a model chose out of the author's own writing, and it is escaped. #} {% extends "base.html" %} {% from "mirrorwall/components.html" import badge, empty_state %} {% block content %}

{{ project.title }} — plan

Back to the project · Workspace

{% if edit_refusal %} {% endif %}

Requirements

{% if requirements %}
{% for requirement in requirements %} {% endfor %}
Compiled requirements, with the material that supports each
KeyRequirementClass Checked bySourceUnits
{{ requirement.key }} {{ requirement.text }} {{ badge("blocking" if requirement.blocking else "advisory", tone="warning" if requirement.blocking else "neutral") }} {{ requirement.checks }} {% if not requirement.mechanical %}{{ badge("model review only" if requirement.blocking else "model-assisted", tone="warning" if requirement.blocking else "neutral") }}{% endif %} {{ requirement.source }}
{{ requirement.quote }}
{{ requirement.units | join(", ") or "—" }}
{% else %} {{ empty_state("No requirements compiled yet.") }} {% endif %}

Units

{% if units %}
{% for unit in units %} {% endfor %}
The unit plan, in reading order
KeyTitleGoalRequirementsState
{{ unit.key }} {{ unit.title }} {{ unit.goal }} {{ unit.requirements or "—" }} {{ badge(unit.state, tone="success" if unit.state == "committed" else "neutral") }}
{% else %} {{ empty_state("No plan yet. Build one to begin.") }} {% endif %} {% if units %}

Edit the plan

Every edit re-checks the whole plan. One that would leave a blocking requirement with no unit responsible for it is refused, and the requirement is named. Structural edits (reorder, split, merge) are refused once a unit holds committed text — finished work is never renumbered out from under itself.

Move a unit

Split a unit

Merge units

Reassign requirements

Rewrite a goal

{% endif %} {% endblock %}