@zalom/plastic 2.0.0-alpha.16 → 2.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -577,30 +577,69 @@ module ReportScreen
|
|
|
577
577
|
rows.compact
|
|
578
578
|
end
|
|
579
579
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
580
|
+
# Intent 331b (plan.md, "The one non-additive edit"): the standalone-token
|
|
581
|
+
# rule, extracted so `action_file_for` (the plan screen's Action column)
|
|
582
|
+
# calls the exact same rule as `matching_action_heading` and the two can
|
|
583
|
+
# never drift on what counts as a match.
|
|
584
|
+
def self.heading_tokens(heading)
|
|
585
|
+
heading.to_s.sub(/\A#+\s*/, "").split(/[^A-Za-z0-9]+/)
|
|
586
|
+
end
|
|
587
|
+
|
|
588
|
+
# Rows 25-27: D19/D1r - the label must appear as a standalone token in an
|
|
589
|
+
# action file heading (any level), AND that heading must own at least one
|
|
590
|
+
# matrix data row - a heading that only names the label, with no table
|
|
591
|
+
# beneath it (or a table with a separator but no data row), is skipped and
|
|
592
|
+
# the walk keeps going. Lexicographic path order (D8), then file order.
|
|
593
|
+
#
|
|
594
|
+
# Merge note (322 into alpha, 2026-09-05): 322's table-owning rule and 331b's
|
|
595
|
+
# extracted `heading_tokens` are both kept. The token split now comes from the
|
|
596
|
+
# shared helper so `action_file_for` cannot drift from this walk, while the
|
|
597
|
+
# `table_rows(body).any?` guard stays the thing that decides the match.
|
|
598
|
+
def self.matching_action_heading(intent_dir, label)
|
|
599
|
+
Dir.glob(File.join(intent_dir, "actions", "*.md")).sort.each do |path|
|
|
600
|
+
split_by_headings(File.read(path)).each do |heading, body|
|
|
601
|
+
next unless heading_tokens(heading).include?(label)
|
|
602
|
+
return [heading, body] if table_rows(body).any?
|
|
603
|
+
end
|
|
604
|
+
end
|
|
605
|
+
[nil, nil]
|
|
606
|
+
end
|
|
607
|
+
|
|
608
|
+
# D3r: the row-cell fallback, for the shape where the label never appears in
|
|
609
|
+
# a heading at all, only as the first cell of a matrix data row. Restricted
|
|
610
|
+
# to tables under a heading that names itself a matrix (/matrix/i) - never a
|
|
611
|
+
# step list or any other table - so it cannot answer for a record that has
|
|
612
|
+
# no matrix anywhere (the close-gate defeat the plan review measured).
|
|
613
|
+
# Emphasis (bold/italic/code) is stripped from the compared cell; the count
|
|
614
|
+
# sums matching rows across every matrix heading, in every action file.
|
|
615
|
+
def self.matching_matrix_rows(intent_dir, label)
|
|
616
|
+
count = 0
|
|
592
617
|
Dir.glob(File.join(intent_dir, "actions", "*.md")).sort.each do |path|
|
|
593
618
|
split_by_headings(File.read(path)).each do |heading, body|
|
|
594
|
-
|
|
619
|
+
next unless heading.to_s.match?(/matrix/i)
|
|
620
|
+
table_rows(body).each do |cells|
|
|
621
|
+
cell = cells[0].to_s.gsub(/[*_`]/, "").strip
|
|
622
|
+
count += 1 if cell == label
|
|
623
|
+
end
|
|
595
624
|
end
|
|
596
625
|
end
|
|
597
|
-
|
|
626
|
+
count
|
|
598
627
|
end
|
|
599
628
|
|
|
629
|
+
# D7: a label with no letter never resolves, on either path - it is a
|
|
630
|
+
# bullet-derived Delivered number (delivered_rows), never a label anyone
|
|
631
|
+
# wrote, and would otherwise fabricate proof from a numbered heading like
|
|
632
|
+
# "## 1. What this intent is" or from a numbered matrix row-cell column.
|
|
600
633
|
def self.proven_by(intent_dir, label)
|
|
634
|
+
return NOT_RECORDED unless label.to_s.match?(/[A-Za-z]/)
|
|
635
|
+
|
|
601
636
|
_heading, body = matching_action_heading(intent_dir, label)
|
|
602
|
-
|
|
603
|
-
|
|
637
|
+
if body
|
|
638
|
+
n = table_rows(body).length
|
|
639
|
+
return n.positive? ? "#{n} test#{n == 1 ? '' : 's'}" : NOT_RECORDED
|
|
640
|
+
end
|
|
641
|
+
|
|
642
|
+
n = matching_matrix_rows(intent_dir, label)
|
|
604
643
|
n.positive? ? "#{n} test#{n == 1 ? '' : 's'}" : NOT_RECORDED
|
|
605
644
|
end
|
|
606
645
|
|
|
@@ -67,9 +67,10 @@ fill `## Summary`, `## Delivered`, `## Verification`, `## Follow-ups`. `## Deliv
|
|
|
67
67
|
`| Row | What |` table: one row per thing delivered, in plain wording a reader
|
|
68
68
|
recognizes, not a method name or an implementation summary (that detail
|
|
69
69
|
belongs in `## Summary`). Each row's label must appear as a standalone token
|
|
70
|
-
in an action-file heading (`### S1 - ...`
|
|
71
|
-
|
|
72
|
-
|
|
70
|
+
in an action-file heading that owns the matrix table (`### S1 - ...` with a
|
|
71
|
+
table beneath it proves row S1; a table-less heading naming the label is
|
|
72
|
+
skipped); that heading's matrix rows become the row's Proven-by cell on
|
|
73
|
+
`report-screen delivered`'s post-delivery screen. `## Needs you` is the literal None or a
|
|
73
74
|
`| N | What | Why |` table. On abandon, `## Summary` states the abandonment reason and the trail (see Pivot
|
|
74
75
|
below). A placeholder outcome.md is backfilled from the record instead, with the
|
|
75
76
|
close's disposition and the `--outcome-summary` line as its summary. Also author
|
|
@@ -75,7 +75,7 @@ Apply the auto skill's risk rule to the executor's return and the diff: a matrix
|
|
|
75
75
|
|
|
76
76
|
Whenever a review verdict returns - the plan review before code, or the post-execution review above - the lead appends a `Review` line: `ruby ~/.plastic/scripts/savepoint-note <intent_dir> --kind Review --text "<verdict, what changed>"` (intent 317, D17). This is the other half of what `report-screen delay` reads.
|
|
77
77
|
|
|
78
|
-
**The D19 heading convention.** An action file's `## Delivered` row (in `outcome.md`) is proven by
|
|
78
|
+
**The D19 heading convention.** An action file's `## Delivered` row (in `outcome.md`) is proven by the first `actions/ACTION_N.md` heading that carries that row's label as a standalone token AND owns the matrix table (322 D1r) - `### Row A -` with a table beneath it proves row A, `### S1 -` proves row S1; a heading that only names the label, with no table under it, is skipped. Write action-file section headings so the label they prove is unambiguous (never a substring another label could also match, like `A` inside `AB`); `report-screen delivered`'s Proven-by column renders `not recorded` when no heading owns a matching table and no matrix row cell carries the label either.
|
|
79
79
|
|
|
80
80
|
### Step 4: Update Intent and Complete
|
|
81
81
|
Capture observations in `## Insights`. When ALL checklist items are checked:
|
package/templates/outcome.md
CHANGED
|
@@ -10,8 +10,11 @@ disposition: delivered|abandoned
|
|
|
10
10
|
<!-- One row per thing delivered, in plain wording a reader recognizes, not
|
|
11
11
|
an implementation summary; the technical detail belongs in ## Summary. Each
|
|
12
12
|
row's label must appear as a standalone token in an actions/*.md heading
|
|
13
|
-
(for example "### S1 - ..."
|
|
14
|
-
|
|
13
|
+
that owns the matrix table (for example "### S1 - ..." with a table beneath
|
|
14
|
+
it proves row S1); that heading's matrix rows become the row's Proven-by
|
|
15
|
+
cell on the delivered screen (intent 317 D19, 317a, 322 D1r). A label with no
|
|
16
|
+
owning heading falls back to a matrix row cell that carries it, when one
|
|
17
|
+
under a heading named "matrix" exists (322 D3r). -->
|
|
15
18
|
| Row | What |
|
|
16
19
|
| --- | --- |
|
|
17
20
|
| S1 | ... |
|