| name | dialogue-harvest |
| description | Mines improvement insights from long-form AI dialogue logs and long texts — an external or pasted corpus, not the current session (current-session wrap-up belongs to harvest-loop). First operation is sycophancy removal — separates speakers, strips the counterpart's agreement/restatement spans, converts the user's own utterances into falsifiable propositions, and labels each proposition induced (frame first introduced by the counterpart) or independent (originated with the user). Ships a drop counter so removed material is visible, never silently lost. Triggered by "mine insights from this chat log", "이 대화록에서 통찰 캐줘", "strip the agreement and show me what's actually mine", "동조 걷어내고 알맹이만", "what did I actually contribute in this thread". |
| user-invocable | true |
| allowed-tools | ["Read","Grep","Glob"] |
| model | sonnet |
dialogue-harvest
Extracts the load-bearing propositions from a long AI-human dialogue (or long text) after
removing the counterpart's sycophancy. Fills the gap between FH's loading assets
(corpus-grounding-expander, video-ingest) and its mining assets (frontier-digest = feed items,
field-harvest = git history, harvest-loop = session records): none of those mines an argument-shaped
corpus, and a naive summarizer run on an AI dialogue returns "the user made several excellent
points" — worthless, because most of the volume is agreement.
Why the first operation is sycophancy removal: AI dialogue logs are dominated by agreement and
restatement. Without stripping them first, extraction inflates the user's contribution; without
provenance labeling (Step 4), "my insight" and "a frame the counterpart planted" are
indistinguishable — which is exactly the failure this skill exists to prevent.
Triggers
- "mine insights from this chat log" / "이 대화록에서 통찰 캐줘"
- "strip the agreement and show me what's actually mine" / "동조 걷어내고 알맹이만"
- "what did I actually contribute in this thread" / "이 대화에서 내 몫이 뭐였지"
- "turn this dialogue into propositions" / "이 대담 명제로 정리해줘"
/dialogue-harvest {path or pasted log}
Boundary: wrapping up the current session → harvest-loop; this skill mines an
external/pasted dialogue corpus.
Step 0. Input Acquisition
- Path provided → Read the file.
- Pasted log → use as-is.
- No speaker structure detectable (no turn markers, no names, no quoting pattern) → stop and ask:
Speaker separation is the first operation and it needs turn boundaries. Who said what?
(Provide turn markers, or confirm the text is single-author — single-author texts skip
Steps 1–2 and go straight to proposition-ization.)
Single-author path: skip Steps 1–2, Step 4 stamps every proposition independent (no
counterpart exists), and the Step 6 counterpart sections read n/a.
Step 1. Speaker Separation (mechanical when markers exist)
Split the log into turns and attribute each to USER or COUNTERPART. If markers are absent but
inference is possible, proceed and stamp the output header speaker-inference: judged — never
present inferred attribution as given.
Step 2. Sycophancy Strip (one grep-able + two judged classes, drop-counted)
Remove COUNTERPART spans in these classes, counting every removal by class. Only the first
class is mechanical; the other two are judgment calls and their drops are marked (judged) in the
counter — never presented as grep certainty:
| Class | Check | Detection |
|---|
| Praise/agreement lexicon | grep-able | grep for praise-class tokens (sharp/brilliant/exactly right/정확한 지적/탁월한/완벽한 …) — extend the pattern list per corpus language |
| Restatement | judged | counterpart paragraph whose content substantially re-says the user's immediately-preceding utterance (high term overlap, no new claim) |
| Closing filler | judged | session pleasantries carrying no claim |
Multi-class span: a span matching more than one class is counted once, under the first
matching class in the table order above.
Drop counter is mandatory: silent drops are material loss (the qasp loader precedent — unused
material does not scream). Every stripped span and every non-propositional user turn appears in the
Step 6 accounting. Counterpart turns that introduce a frame or claim are retained — they are
the provenance source for Step 4, not noise.
Language note: the praise-token list is language-specific. On a corpus language not yet in the
list, extend the patterns first, then construct (or use, if shipped) a known pair in that
language and re-run calibration — re-running an English-only pair after adding Korean tokens
exercises nothing (vacuous pass). An ASCII-token scan over a Korean corpus is the measured
false-positive precedent. calibration_pair.md ships English + Korean sections.
Step 3. Proposition-ization (user utterances only)
Convert each remaining USER utterance into a falsifiable statement (a form you can ask true/false
of), keeping a source reference (turn id / line) per proposition. Meaning must not drift: the
proposition is a compression of the user's claim, not an improvement of it.
Step 4. Provenance Labeling — induced vs independent (the differentiator)
For each proposition, find the first occurrence of its core frame/key terms in the log:
- First occurrence is in a USER turn → independent.
- First occurrence is in a COUNTERPART turn (the user then adopted/echoed it) → induced.
- Ambiguous (shared vocabulary, gradual convergence) → label induced? — the degrade direction
is toward the induced flag, because mislabeling a planted frame as "my insight" is the harm this
skill exists to catch; the reverse error only costs modesty.
Counterpart-authored content the user selected as valuable is listed separately, marked
"selection, not authorship" — selection is a real act but must not be recorded as the user's claim.
Step 5. Verification-Status Column
Each proposition gets a status: mechanically checkable / falsifiable-but-untested /
unfalsifiable (axiom-only use) / speculation. Unfalsifiable propositions are still listed — flagged
so they are never later cited as established facts.
Step 6. Output + Accounting + Routing (proposal-only)
[dialogue-harvest output]
Corpus: {source} | speaker-inference: given | judged
calibration: run-this-session | previously-verified {date} ← declare every run (L2 guard)
── Propositions ──
| # | proposition | source ref | provenance | verification status |
── Counterpart-originated (selection ≠ authorship) ──
| item | first-occurrence ref |
── Accounting (mandatory identity, turn-based) ──
user turns N = propositionized turns + dropped turns (dropped listed by reason)
propositions total: P (a turn may yield several — counted separately, never forced 1:1)
counterpart spans stripped: {count by class, judged classes marked} · retained as frame-source: {count}
── Routing proposals (no auto-write) ──
{insight → fh_signal / memory / CHAMBER-CANDIDATE / project track — one line each, operator decides}
Routing is proposal-only: this skill writes nothing outside its output block.
Done When
- Accounting identity holds — user turns = propositionized turns + dropped turns, both lists
visible; proposition total reported separately (a turn may carry multiple propositions)
(check-class: mandatory-pass, mechanical count).
- Every proposition carries a source ref + provenance label (independent / induced / induced?)
(check-class: mandatory-pass).
- Calibration pair separates — running the skill on
calibration_pair.md (shipped beside this
file, English + Korean sections) reproduces its known answers: known-independent → independent,
known-induced → induced, drop counted. Required on first use and whenever the praise-pattern list
changes; a corpus language with no shipped section requires constructing that language's known
pair first — re-running an existing-language pair for a new language is a vacuous pass, not a
measurement (check-class: measured; declare the result in the output header
calibration: field).
- Propositions are faithful to source spans — no meaning drift (check-class: judged;
adversarial pairing:
phantom-quench back-trace of each proposition to its source ref — a
proposition whose source span does not support it is an Unsupported finding).
Independence
Independently executable: Read/Grep only, no other FH skill required. phantom-quench is the
adversarial pairing for the judged condition, not a runtime dependency. Works standalone
(plugin-only install).