{% for piece in row %}{% if piece.status == 'anchored' %}{{ piece.text }}{% else %}{{ piece.text }}{% endif %} {% endfor %}
{% endif %}{% endfor %}{% extends "base.html" %} {% block title %}{{ t('interview.title') }} {{ conversation.id }} - {{ t('app.title') }}{% endblock %} {% block content %}
{{ t('interview.tokens', input=conversation.usage.input_tokens, output=conversation.usage.output_tokens) }}{% if spent is not none and (conversation.usage.input_tokens or conversation.usage.output_tokens) %}, {{ t('interview.spent', amount='%.4f'|format(spent)) }}{% endif %}
{% if not engine.ready %} {% include "_engine.html" %} {% endif %}{{ t('interview.said') }}
{{ t('interview.asked') }}
{{ moment.text }}
{{ t('interview.sheet_changed') }}
{% elif notice == 'first-line-missing' %}{{ t('interview.sheet_first_line_missing') }}
{% elif notice == 'turn-running' %}{{ t('interview.error_turn_running') }}
{% endif %}{{ t('interview.sheet_hint') }}
{{ t('interview.sheet_problems') }}
{{ t('interview.sheet_problems_hint') }}
{{ t('interview.sheet_approved_notice') }}
{{ t('interview.sheet_closed_notice') }}
{% elif conversation.state == 'open' %} {# Asking for the sheet is the person's call: they are the one who knows the interview has enough material. The turn behind this button requires the tool, which is what makes the mechanism fire on a model that would otherwise answer the sheet in prose. #} {# How much material is on the table. Beside the sentence the engine writes every turn, never instead of it: what is missing is a judgement about the material and only that sentence carries it. This says how much there is, and it shows its counts, so the percentage is a reading of something somebody can check rather than a verdict of its own. #}{{ t('interview.sufficiency', **gauge) }} {{ t('interview.sufficiency_counts', **gauge) }}
{{ t('interview.sufficiency_hint') }}
{# Not before the first turn. A sheet asked for then is a sheet the model has to invent, which is the failure the sheet exists to catch, and the server refuses it: this is the same rule on the screen instead of behind a click. Hidden rather than absent, because the page does not reload between two interview turns and the client reveals it on the frame that says the first words reached disk. #}{{ t('interview.sheet_ask_hint') }}
{{ t('interview.awaiting') }}
{% else %}{{ t('interview.closed_notice', post=conversation.post) }}
{% endif %} {% if sheet and sheet.state == 'approved' %}{{ t('interview.draft_changed') }}
{% endif %}{{ t('interview.draft_hint') }}
{% if conversation.state == 'open' %} {% if trace %} {# The revision loop of the skill, made a box. What is typed here is kept and joins the Said side: the hint says so, because somebody has to know that a correction typed here is quotable and a request typed here is on the record. The button reads it; nothing is appended to the interview. #} {% if conversation.revisions %}{{ t('interview.revision_asked', stamp=asked.asked) }}
{{ asked.text }}
{{ scope.text if scope }}{% endif %}
{{ t('interview.revision_hint') }}
{# A placeholder that teaches by example rather than describing the field. Somebody who reads "your request" writes "make it better". #} {# Which interview this box belongs to. What is typed here outlives the page, in the browser's own store and per interview, so a request half written for one post never turns up under another. #} {% endif %} {# The scope, on the action line rather than in a paragraph above it. It is the sentence somebody reads with their hand already on the button. #}{{ t('interview.revision_scope_line') }}
{# Where a drafting turn talks: here, beside the scope, the echo of the passage and the box, and not in the thread at the top of the page. The refusal contract of `linkedin-post` means a turn can answer with a question instead of a post, and an answer shown a screen away from its own question is answered by picking the passage again by hand. Empty until a turn speaks, and emptied by the next one. #} {% endif %} {% if not trace %}{{ t('interview.draft_none') }}
{% else %}{{ t('interview.draft_version', number=trace.version) }} {{ t('interview.draft_written', stamp=trace.written) }}{% if trace.restored %}, {{ t('interview.draft_restored', stamp=trace.restored) }}{% endif %}
{# Both only from the second version on, which is the rule the resume button and the passage picker already follow: an affordance with no history behind it is not on the screen, and a legend about a previous version is a legend about nothing. #} {% if trace.version > 1 %}{{ t('interview.moved_legend') }}
{% endif %}{% for piece in row %}{% if piece.status == 'anchored' %}{{ piece.text }}{% else %}{{ piece.text }}{% endif %} {% endfor %}
{% endif %}{% endfor %}{{ t('interview.lint_failed') }}
{% endif %}{{ findings }}
{{ t('interview.trace_hint') }}
{{ t('interview.trace_counts', **trace.counts) }}
{% if trace.problems %}{{ t('interview.trace_problems') }}
{{ t('interview.trace_none') }}
{% elif not trace.counts.unanchored and trace.counts.anchored == trace.verdicts|length %}{{ t('interview.trace_clean') }}
{% endif %}{{ t('interview.anchor_' ~ verdict.status) }}
{{ t('interview.' ~ verdict.hint) }}
{{ t('interview.notes_hint') }}
{{ t('interview.archive_' ~ archive_problem|replace('-', '_')) }}
{% endif %} {% if conversation.state == 'open' %} {# The step the skill says decides whether any of this was worth doing. The classification is the person's: none of it is derivable from a body of text, and a value guessed here is a guess counted in every ratio. #}{{ t('interview.archive_hint') }}
{{ t('interview.bank_hint') }}
{{ t('interview.discard_hint', path=conversation.id) }}
{% endblock %}