Przeglądaj źródła

Goal detail: pending reviews lead the acting column

Goal 41 T6 amendment ('actions surface'). While a plan review or a
completion review is pending, that review now renders as its own
accented card at the TOP of the act column (stm-if ordering on the
slot's plan_pending_block / completion_pending_block scalars) instead
of living inside the fifth card or the blocks loop. The plan card
keeps only the history expander (always available); the blocks loop
defers completion-family rows to the leading card. resolveReviewBlock
gains the completion_pending_block shape so the shared remarks queue
still resolves its block from whichever [data-plan-review] container
rendered it.

goalui.py gains the leading-review order check (review < status head
< blocks < plan history) and the two review cards join the act-column
marker list. Verified: full suite 36/36 bundles, 1855 passed 0
failed; goalui 142/0, goals 191/0, resurrect 37/0, forcewake 28/0,
push 76/0.
saddle-ClankerSaddle 1 dzień temu
rodzic
commit
74c55e69eb
3 zmienionych plików z 102 dodań i 72 usunięć
  1. 6 0
      src/pages/app.css
  2. 88 69
      src/pages/goal_detail.html
  3. 8 3
      test/bundles/goalui.py

+ 6 - 0
src/pages/app.css

@@ -1394,6 +1394,12 @@ td .truncate.repo-url {
    every colour/spacing value consumes a --spry-* token).
    every colour/spacing value consumes a --spry-* token).
    ========================================================================== */
    ========================================================================== */
 
 
+/* The leading review cards (goal 41 T6 "actions surface"): a pending
+   plan or completion review renders as its own card at the TOP of
+   the acting column, accented like the status head so the open
+   decision reads before anything else. */
+.plan-review-card { border-left: 4px solid var(--spry-accent); }
+
 /* The one-line state strip (ux-notes §5 A): status badge, the
 /* The one-line state strip (ux-notes §5 A): status badge, the
    open-item verdict, the primary lifecycle button — one glance
    open-item verdict, the primary lifecycle button — one glance
    before anything else on the page. A quiet accent-tinted panel so
    before anything else on the page. A quiet accent-tinted panel so

+ 88 - 69
src/pages/goal_detail.html

@@ -150,11 +150,11 @@
             // now lives once); only the block resolution is page
             // now lives once); only the block resolution is page
             // state.
             // state.
             // Plan 16 S2: the block for a review container resolves
             // Plan 16 S2: the block for a review container resolves
-            // from the ACTUAL [data-plan-review] element - the pending
-            // completion review renders as an attention block (NOT the
-            // plan section), so goal.plan_pending_block alone never
-            // resolves it; every open block plus the plan section's
-            // row are all candidates.
+            // from the ACTUAL [data-plan-review] element — the
+            // pending completion review renders as a LEADING review
+            // card (goal 41 T6), so goal.plan_pending_block alone
+            // never resolves it; the slot's three review shapes plus
+            // every open block are all candidates.
             function resolveReviewBlock(id) {
             function resolveReviewBlock(id) {
                 var goal = statum.read('goal');
                 var goal = statum.read('goal');
                 if (!goal) return null;
                 if (!goal) return null;
@@ -162,6 +162,10 @@
                 (goal.open_blocks || []).forEach(function (candidate) {
                 (goal.open_blocks || []).forEach(function (candidate) {
                     if (String(candidate.id) === String(id)) block = candidate;
                     if (String(candidate.id) === String(id)) block = candidate;
                 });
                 });
+                if (!block && goal.completion_pending_block
+                        && String(goal.completion_pending_block.id) === String(id)) {
+                    block = goal.completion_pending_block;
+                }
                 if (!block && goal.plan_pending_block
                 if (!block && goal.plan_pending_block
                         && String(goal.plan_pending_block.id) === String(id)) {
                         && String(goal.plan_pending_block.id) === String(id)) {
                     block = goal.plan_pending_block;
                     block = goal.plan_pending_block;
@@ -270,8 +274,72 @@
             <div class="goal-columns with-sidebar" data-goal-columns>
             <div class="goal-columns with-sidebar" data-goal-columns>
                 <div class="stack" data-goal-act>
                 <div class="stack" data-goal-act>
 
 
-            <!-- Status head (first in the ACT column, always):
-                 lifecycle badge, branch pair with the
+            <!-- GOAL 41 T6 ("actions surface"): while a plan review is
+                 pending, the review surface LEADS the acting column
+                 (stm-if ordering by state) — the reader answers before
+                 anything else. The plan-history card below renders
+                 only when nothing is pending. -->
+            <section class="card plan-review-card goal-section"
+                     stm-if="goal.plan_pending_block != null && goal.plan_pending_block != false"
+                     id="goal-sec-plan-review">
+                <h3>Plan review</h3>
+                <div class="plan-review" data-plan-review
+                     stm-attribute.data-block-id="goal.plan_pending_block.id">
+                    <h4>Plan submitted for review</h4>
+                    <div class="md rfc-body goal-body" data-plan-body
+                         stm-markdown="goal.plan_pending_block.body">revision</div>
+                    <div class="actions">
+                        <form stm-action="goal.plan_pending_block.answer_action" class="cluster">
+                            <input type="hidden" name="verdict" value="accept">
+                            <button type="submit" class="btn-primary" data-plan-accept>Approve plan</button>
+                        </form>
+                        <button type="button" data-plan-toggle>Reject with feedback</button>
+                    </div>
+                    <div data-plan-feedback hidden>
+                        <p class="text-muted">Highlight plan text to attach a remark to it — the queue
+                            rides the rejection numbered, then clears. Approving ignores the queue.</p>
+                        <ul class="plan-comments" data-plan-remarks></ul>
+                        <textarea name="feedback" rows="2"
+                                  placeholder="Additional feedback (optional)"></textarea>
+                        <button type="button" class="btn-primary" data-plan-submit>Submit feedback</button>
+                    </div>
+                </div>
+            </section>
+
+            <!-- GOAL 41 T6 ("actions surface"): the pending completion
+                 review leads the acting column the same way — hoisted
+                 out of the blocks loop (which skips review rows) and
+                 keyed on the slot's completion_pending_block. -->
+            <section class="card plan-review-card goal-section"
+                     stm-if="goal.completion_pending_block != null && goal.completion_pending_block != false"
+                     id="goal-sec-completion-review">
+                <h3>Completion review</h3>
+                <div class="plan-review" data-plan-review
+                     stm-attribute.data-block-id="goal.completion_pending_block.id">
+                    <pstm-fragment name="goal-branches"/>
+                    <pstm-fragment name="goal-compare"/>
+                    <div class="md rfc-body goal-body" data-plan-body
+                         stm-markdown="goal.completion_pending_block.body">report</div>
+                    <div class="actions">
+                        <form stm-action="goal.completion_pending_block.answer_action" class="cluster">
+                            <input type="hidden" name="verdict" value="accept">
+                            <button type="submit" class="btn-primary" data-plan-accept>Accept goal</button>
+                        </form>
+                        <button type="button" data-plan-toggle>Reject with feedback</button>
+                    </div>
+                    <div data-plan-feedback hidden>
+                        <p class="text-muted">Highlight report text to attach a remark to it — the queue
+                            rides the rejection numbered, then clears. Accepting ignores the queue.</p>
+                        <ul class="plan-comments" data-plan-remarks></ul>
+                        <textarea name="feedback" rows="2"
+                                  placeholder="Additional feedback (optional)"></textarea>
+                        <button type="button" class="btn-primary" data-plan-submit>Submit feedback</button>
+                    </div>
+                </div>
+            </section>
+
+            <!-- Status head (first in the ACT column while no review
+                 awaits): lifecycle badge, branch pair with the
                  daemon-reported push-state chips, priority,
                  daemon-reported push-state chips, priority,
                  timestamps, the assigned/parking agent saddle and
                  timestamps, the assigned/parking agent saddle and
                  the FULL lifecycle ladder — with run control parity
                  the FULL lifecycle ladder — with run control parity
@@ -364,39 +432,15 @@
                      id="goal-sec-blocks">
                      id="goal-sec-blocks">
                 <h3>Goal agent blocks</h3>
                 <h3>Goal agent blocks</h3>
                 <div stm-for-block-in="goal.open_blocks" class="goal-block">
                 <div stm-for-block-in="goal.open_blocks" class="goal-block">
-                    <p><span stm-attribute.class="'badge badge-block-' + block.block_type"
+                    <!-- A pending completion review renders in the
+                         LEADING completion-review card above (goal 41
+                         T6 "actions surface"); the loop shows every
+                         other open block — questions and RFCs with
+                         full markdown bodies and inline answer forms. -->
+                    <p stm-if="!block.is_completion_review"><span stm-attribute.class="'badge badge-block-' + block.block_type"
                              stm-text="block.block_type">kind</span>
                              stm-text="block.block_type">kind</span>
                         <strong stm-text="block.question">question</strong>
                         <strong stm-text="block.question">question</strong>
                         <span class="text-muted" stm-text="block.created_display">when</span></p>
                         <span class="text-muted" stm-text="block.created_display">when</span></p>
-                    <!-- The pending completion review renders in the rich
-                         review form (highlight-remarks queue shared with
-                         the plan review; push chips + compare above the
-                         report — chips are advisory, the push rule is
-                         enforced daemon-side at the agent's completion
-                         attempt). -->
-                    <div stm-if="block.is_completion_review"
-                         class="plan-review" data-plan-review
-                         stm-attribute.data-block-id="block.id">
-                        <pstm-fragment name="goal-branches"/>
-                        <pstm-fragment name="goal-compare"/>
-                        <div class="md rfc-body goal-body" data-plan-body
-                             stm-markdown="block.body">report</div>
-                        <div class="actions">
-                            <form stm-action="block.answer_action" class="cluster">
-                                <input type="hidden" name="verdict" value="accept">
-                                <button type="submit" class="btn-primary" data-plan-accept>Accept goal</button>
-                            </form>
-                            <button type="button" data-plan-toggle>Reject with feedback</button>
-                        </div>
-                        <div data-plan-feedback hidden>
-                            <p class="text-muted">Highlight report text to attach a remark to it — the queue
-                                rides the rejection numbered, then clears. Accepting ignores the queue.</p>
-                            <ul class="plan-comments" data-plan-remarks></ul>
-                            <textarea name="feedback" rows="2"
-                                      placeholder="Additional feedback (optional)"></textarea>
-                            <button type="button" class="btn-primary" data-plan-submit>Submit feedback</button>
-                        </div>
-                    </div>
                     <div stm-if="!block.is_completion_review">
                     <div stm-if="!block.is_completion_review">
                         <div stm-if="block.show_body && block.body.length > 0"
                         <div stm-if="block.show_body && block.body.length > 0"
                              class="md rfc-body goal-body" stm-markdown="block.body">body</div>
                              class="md rfc-body goal-body" stm-markdown="block.body">body</div>
@@ -431,41 +475,16 @@
                 <div class="md rfc-body goal-body" stm-markdown="goal.completion_report">report</div>
                 <div class="md rfc-body goal-body" stm-markdown="goal.completion_report">report</div>
             </section>
             </section>
 
 
-            <!-- The plan (plan 15 C4): BETWEEN attention and tasks.
-                 While a plan review is open the pending submission
-                 renders EXPANDED with the remarks queue (plan 14 B2);
-                 otherwise the approved plan and the revision history
-                 (approved + rejected) sit behind a collapsed
-                 expander — the goal page leads with what needs a
-                 human, not with settled history. -->
+            <!-- The plan history (plan 15 C4): the approved plan and
+                 the revision history (approved + rejected) sit behind
+                 a collapsed expander — the goal page leads with what
+                 needs a human, not with settled history. While a plan
+                 review is open the LEADING plan-review card above
+                 carries it (this card waits below). -->
             <section class="card goal-section" id="goal-sec-plan">
             <section class="card goal-section" id="goal-sec-plan">
                 <h3>Plan</h3>
                 <h3>Plan</h3>
 
 
-                <div stm-if="goal.plan_pending_block != null && goal.plan_pending_block != false"
-                     class="plan-review" data-plan-review
-                     stm-attribute.data-block-id="goal.plan_pending_block.id">
-                    <h4>Plan submitted for review</h4>
-                    <div class="md rfc-body goal-body" data-plan-body
-                         stm-markdown="goal.plan_pending_block.body">revision</div>
-                    <div class="actions">
-                        <form stm-action="goal.plan_pending_block.answer_action" class="cluster">
-                            <input type="hidden" name="verdict" value="accept">
-                            <button type="submit" class="btn-primary" data-plan-accept>Approve plan</button>
-                        </form>
-                        <button type="button" data-plan-toggle>Reject with feedback</button>
-                    </div>
-                    <div data-plan-feedback hidden>
-                        <p class="text-muted">Highlight plan text to attach a remark to it — the queue
-                            rides the rejection numbered, then clears. Approving ignores the queue.</p>
-                        <ul class="plan-comments" data-plan-remarks></ul>
-                        <textarea name="feedback" rows="2"
-                                  placeholder="Additional feedback (optional)"></textarea>
-                        <button type="button" class="btn-primary" data-plan-submit>Submit feedback</button>
-                    </div>
-                </div>
-
-                <details class="history-expander"
-                         stm-if="goal.plan_pending_block == null || goal.plan_pending_block == false">
+                <details class="history-expander">
                     <summary>Approved plan &amp; revisions (<span
                     <summary>Approved plan &amp; revisions (<span
                             stm-text="goal.plan_revisions.length">0</span>)</summary>
                             stm-text="goal.plan_revisions.length">0</span>)</summary>
                     <div stm-if="goal.plan.length > 0" class="md rfc-body goal-body" data-plan-body
                     <div stm-if="goal.plan.length > 0" class="md rfc-body goal-body" data-plan-body

+ 8 - 3
test/bundles/goalui.py

@@ -126,9 +126,12 @@ def run(ctx):
     check(goal_state(goal)["current_activity"] == "parked awaiting the plan review",
     check(goal_state(goal)["current_activity"] == "parked awaiting the plan review",
           "the head line reads 'parked awaiting the plan review' while one is open")
           "the head line reads 'parked awaiting the plan review' while one is open")
     goal_page = http_get_page(auth, "/goals/%d" % goal)
     goal_page = http_get_page(auth, "/goals/%d" % goal)
-    check(goal_page.index("Goal agent blocks") < goal_page.index("<h3>Plan</h3>")
-          < goal_page.index("<h3>Tasks</h3>"),
-          "the plan section sits between attention and tasks")
+    # Goal 41 T6 ("actions surface"): a pending plan review LEADS the
+    # acting column as its own card — before the status head, the
+    # blocks and the (history-only) plan card.
+    check(goal_page.index("Plan review") < goal_page.index('class="card goal-head')
+          < goal_page.index("Goal agent blocks") < goal_page.index("<h3>Plan</h3>"),
+          "a pending plan review leads the acting column (status, blocks, history after)")
     check("data-plan-review" in goal_page and "Approved plan &amp; revisions" in goal_page,
     check("data-plan-review" in goal_page and "Approved plan &amp; revisions" in goal_page,
           "an open review renders expanded beside the collapsed approved-plan expander")
           "an open review renders expanded beside the collapsed approved-plan expander")
 
 
@@ -441,6 +444,8 @@ def run(ctx):
         {"href": None, "label": "#%d" % goal}],
         {"href": None, "label": "#%d" % goal}],
         "the entrypoint publishes the Dashboard → Goals → #id crumb trail")
         "the entrypoint publishes the Dashboard → Goals → #id crumb trail")
     act_markers = [
     act_markers = [
+        ('id="goal-sec-plan-review"', "plan review (when pending)"),
+        ('id="goal-sec-completion-review"', "completion review (when pending)"),
         ('class="card goal-head goal-section"', "status head"),
         ('class="card goal-head goal-section"', "status head"),
         ("Agent progress", "progress"),
         ("Agent progress", "progress"),
         ("Goal agent blocks", "attention blocks"),
         ("Goal agent blocks", "attention blocks"),