epistemic redo
This commit is contained in:
parent
b80fe2fee7
commit
d113671e96
27
WRITING.md
27
WRITING.md
|
|
@ -59,7 +59,7 @@ no-collapse: true # optional; disables collapsible h2/h3 sections
|
|||
js: scripts/my-widget.js # optional; per-page JS file (see Page scripts)
|
||||
# js: [scripts/a.js, scripts/b.js] # or a list
|
||||
|
||||
# Epistemic Effort — all optional; the entire section is hidden unless `status` is set
|
||||
# Epistemic profile — all optional; the entire section is hidden unless `status` is set
|
||||
status: "Working model" # Draft | Working model | Durable | Refined | Superseded | Deprecated
|
||||
confidence: 72 # 0–100 integer (%)
|
||||
importance: 3 # 1–5 integer (rendered as filled/empty dots ●●●○○)
|
||||
|
|
@ -648,19 +648,26 @@ copies all JS files from `content/` to `_site/` automatically.
|
|||
The epistemic footer section appears when `status` is set. All other fields
|
||||
are optional and are shown or hidden independently.
|
||||
|
||||
| Field | Compact display | Expanded (`<details>`) |
|
||||
|-------|----------------|------------------------|
|
||||
| `status` | chip (always shown if present) | — |
|
||||
| `confidence` | `72%` | — |
|
||||
| `importance` | `●●●○○` | — |
|
||||
| `evidence` | `●●○○○` | — |
|
||||
| Field | Compact rows | Expanded `<dl>` |
|
||||
|-------|-------------|------------------|
|
||||
| *(trust score)* | bordered chip + small-caps "trust" label on the primary row | — |
|
||||
| `status` | small-caps chip on the primary row, alongside the trust chip | — |
|
||||
| `confidence` | `· 72% confidence` | — |
|
||||
| `importance` | `· ●●●○○ importance` | — |
|
||||
| `evidence` | `· ●●○○○ evidence quality` | — |
|
||||
| `scope` | `· average scope` (if set) | — |
|
||||
| `novelty` | `· moderate novelty` (if set) | — |
|
||||
| `practicality` | `· moderate practicality` (if set) | — |
|
||||
| `stability` | — | auto-computed from git history |
|
||||
| `scope` | — | if set |
|
||||
| `novelty` | — | if set |
|
||||
| `practicality` | — | if set |
|
||||
| `last-reviewed` | — | most recent commit date |
|
||||
| `confidence-trend` | — | ↑/↓/→ from last two `confidence-history` entries |
|
||||
|
||||
The **trust score** is auto-computed as `confidence × 0.6 + ((evidence − 1) / 4) × 0.4`,
|
||||
clamped 0–100. It is deliberately narrow: it answers "how much should you trust the
|
||||
central claim?" and nothing else. Importance, scope, novelty, and practicality are
|
||||
*not* folded in — they are orientation signals shown alongside the chip so a high
|
||||
trust score on a personal essay cannot be misread as broad significance.
|
||||
|
||||
**Stability** is auto-computed from `git log --follow` at every build. The
|
||||
heuristic: ≤1 commits or age <14 days → *volatile*; ≤5 commits and age <90
|
||||
days → *revising*; ≤15 commits or age <365 days → *fairly stable*; ≤30
|
||||
|
|
|
|||
|
|
@ -306,13 +306,25 @@ confidenceTrendField = field "confidence-trend" $ \item -> do
|
|||
lastTwo [a, b] = Just (a, b)
|
||||
lastTwo (_ : rest) = lastTwo rest
|
||||
|
||||
-- | @$overall-score$@: weighted composite of confidence (50 %),
|
||||
-- evidence quality (30 %), and importance (20 %), expressed as an
|
||||
-- integer on a 0–100 scale.
|
||||
-- Returns @noResult@ when any contributing field is absent, so
|
||||
-- | @$overall-score$@: weighted composite of confidence (60 %) and
|
||||
-- evidence quality (40 %), expressed as an integer on a 0–100 scale.
|
||||
--
|
||||
-- Importance is intentionally excluded from the score: it answers
|
||||
-- "should you read this?", not "should you trust it?", and folding
|
||||
-- the two together inflated the number and muddied its meaning.
|
||||
-- It still appears in the footer as an independent orientation
|
||||
-- signal — just not as a credibility input.
|
||||
--
|
||||
-- The 1–5 evidence scale is rescaled as @(ev − 1) / 4@ rather than
|
||||
-- plain @ev / 5@. The naive form left a hidden +6 floor (since
|
||||
-- @1/5 = 0.2@) and a midpoint of 0.6 instead of 0.5; the rescale
|
||||
-- makes evidence=1 contribute zero and evidence=3 contribute exactly
|
||||
-- half, so a "true midpoint" entry (conf=50, ev=3) lands on 50.
|
||||
--
|
||||
-- Returns @noResult@ when confidence or evidence is absent, so
|
||||
-- @$if(overall-score)$@ guards the template safely.
|
||||
--
|
||||
-- Formula: raw = conf/100·0.5 + ev/5·0.3 + imp/5·0.2 (0–1)
|
||||
-- Formula: raw = conf/100 · 0.6 + (ev − 1)/4 · 0.4 (0–1)
|
||||
-- score = clamp₀₋₁₀₀(round(raw · 100))
|
||||
overallScoreField :: Context String
|
||||
overallScoreField = field "overall-score" $ \item -> do
|
||||
|
|
@ -320,16 +332,14 @@ overallScoreField = field "overall-score" $ \item -> do
|
|||
let readInt s = readMaybe s :: Maybe Int
|
||||
case ( readInt =<< lookupString "confidence" meta
|
||||
, readInt =<< lookupString "evidence" meta
|
||||
, readInt =<< lookupString "importance" meta
|
||||
) of
|
||||
(Just conf, Just ev, Just imp) ->
|
||||
(Just conf, Just ev) ->
|
||||
let raw :: Double
|
||||
raw = fromIntegral conf / 100.0 * 0.5
|
||||
+ fromIntegral ev / 5.0 * 0.3
|
||||
+ fromIntegral imp / 5.0 * 0.2
|
||||
raw = fromIntegral conf / 100.0 * 0.6
|
||||
+ fromIntegral (ev - 1) / 4.0 * 0.4
|
||||
score = max 0 (min 100 (round (raw * 100.0) :: Int))
|
||||
in return (show score)
|
||||
_ -> fail "overall-score: confidence, evidence, or importance not set"
|
||||
_ -> fail "overall-score: confidence or evidence not set"
|
||||
|
||||
-- | All epistemic context fields composed.
|
||||
epistemicCtx :: Context String
|
||||
|
|
|
|||
3
spec.md
3
spec.md
|
|
@ -145,7 +145,7 @@ Auto-derived at build time: `stability` (from `git log --follow`), `last-reviewe
|
|||
|
||||
**Bottom metadata footer:**
|
||||
- **Version history** — three-tier priority: (1) frontmatter `history` list with authored notes → (2) git log dates (date-only) → (3) `date-created` / `date-modified` fallback. `make build` auto-commits `content/` before building, keeping git history current.
|
||||
- **Epistemic** (if `status` set) — compact: status chip · confidence % · importance dots · evidence dots; expanded `<details>`: stability · scope · novelty · practicality · last reviewed · confidence trend
|
||||
- **Epistemic** (if `status` set) — primary row: trust-score chip + status; labeled rows beneath: confidence · importance · evidence · scope · novelty · practicality (each shown only if its frontmatter field is set); always-visible `<dl>`: stability · last reviewed · confidence trend
|
||||
- **Bibliography** — formatted citations + Further Reading
|
||||
- **Backlinks** — auto-generated; each entry shows source title (link) + collapsible context paragraph
|
||||
|
||||
|
|
@ -648,6 +648,7 @@ Implemented across `build/Stability.hs`, `build/Contexts.hs`, `templates/partial
|
|||
| `$confidence$` | frontmatter `confidence` | via `defaultContext` |
|
||||
| `$importance-dots$` | frontmatter `importance` (1–5) | `●●●○○` rendered in Haskell |
|
||||
| `$evidence-dots$` | frontmatter `evidence` (1–5) | same |
|
||||
| `$overall-score$` | computed from `confidence` + `evidence` | trust score: `conf/100 · 0.6 + (ev−1)/4 · 0.4`, clamped 0–100. Importance/scope/novelty/practicality intentionally excluded — see colophon "Living Documents" for the rationale. |
|
||||
| `$confidence-trend$` | frontmatter `confidence-history` list | ↑ / ↓ / → from last two entries |
|
||||
| `$stability$` | auto-computed via `git log --follow` | always resolves; never fails |
|
||||
| `$last-reviewed$` | most recent commit date | formatted "%-d %B %Y"; `noResult` if no commits |
|
||||
|
|
|
|||
|
|
@ -627,15 +627,6 @@ nav.site-nav {
|
|||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
/* When the score box is present, suppress the link-level underline and
|
||||
restore it only on the label text — leaves the gap and box undecorated. */
|
||||
.meta-pagelinks a:has(.meta-overall-score):hover {
|
||||
text-decoration: none;
|
||||
}
|
||||
.meta-pagelinks a:has(.meta-overall-score):hover .ep-link-label {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 2px;
|
||||
}
|
||||
.meta-pagelinks a + a::before {
|
||||
content: " · ";
|
||||
color: var(--border);
|
||||
|
|
@ -644,6 +635,19 @@ nav.site-nav {
|
|||
white-space: pre;
|
||||
}
|
||||
|
||||
/* Top-of-page parallel tag strip — surfaces the full epistemic profile
|
||||
inline so a reader sees status, trust score, and every orientation
|
||||
axis at a glance, without scrolling to the footer. The trust chip
|
||||
anchors the left edge; status sits next to it; the labeled rows
|
||||
follow with their leading centerdot separators. Wraps freely. */
|
||||
.meta-epistemic-strip {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
justify-content: center;
|
||||
gap: 0.35rem 0.55rem;
|
||||
}
|
||||
|
||||
|
||||
/* ============================================================
|
||||
BOTTOM METADATA FOOTER
|
||||
|
|
@ -808,15 +812,6 @@ details[open] > .backlink-summary::before {
|
|||
with an expandable <details> for the full profile.
|
||||
============================================================ */
|
||||
|
||||
/* Compact row — chips laid out inline */
|
||||
.ep-compact {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
align-items: baseline;
|
||||
gap: 0.35rem 0.55rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
/* Status chip */
|
||||
.ep-status {
|
||||
font-family: var(--font-sans);
|
||||
|
|
@ -826,15 +821,18 @@ details[open] > .backlink-summary::before {
|
|||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
/* Confidence percentage */
|
||||
.ep-confidence {
|
||||
/* Every labeled row beneath the primary line shares one class so new
|
||||
epistemic fields can be added in the template without touching CSS.
|
||||
Used by confidence, importance, evidence, scope, novelty, practicality. */
|
||||
.ep-row {
|
||||
font-family: var(--font-sans);
|
||||
font-size: 0.72rem;
|
||||
color: var(--text-faint);
|
||||
}
|
||||
.ep-confidence::before { content: "·\00a0"; color: var(--border); }
|
||||
.ep-row::before { content: "·\00a0"; color: var(--border); }
|
||||
|
||||
/* Dot scale (importance / evidence) */
|
||||
/* Dot scale (importance / evidence) — only ever used nested inside an
|
||||
.ep-row wrapper, which already supplies the centerdot separator. */
|
||||
.ep-dots {
|
||||
font-size: 0.55rem;
|
||||
letter-spacing: 0.12em;
|
||||
|
|
@ -842,34 +840,30 @@ details[open] > .backlink-summary::before {
|
|||
line-height: 1;
|
||||
vertical-align: 0.15em;
|
||||
}
|
||||
.ep-dots::before { content: "·\00a0"; color: var(--border); font-size: 0.72rem; vertical-align: 0; }
|
||||
.ep-row .ep-dots::before { content: none; }
|
||||
|
||||
/* Expandable detail block */
|
||||
.ep-details {
|
||||
margin-top: 0.1rem;
|
||||
}
|
||||
|
||||
.ep-summary {
|
||||
font-size: 0.68rem;
|
||||
/* Trust chip on the primary row — bordered numeric chip plus a small-caps
|
||||
"trust" label, mirroring .ep-status typography so the two sit together. */
|
||||
.ep-trust {
|
||||
font-family: var(--font-sans);
|
||||
color: var(--text-faint);
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
user-select: none;
|
||||
font-size: 0.72rem;
|
||||
font-variant-caps: all-small-caps;
|
||||
letter-spacing: 0.05em;
|
||||
color: var(--text-muted);
|
||||
}
|
||||
|
||||
.ep-summary::-webkit-details-marker { display: none; }
|
||||
|
||||
.ep-summary::before {
|
||||
content: "▸\00a0";
|
||||
font-size: 0.6em;
|
||||
vertical-align: 0.1em;
|
||||
.ep-score {
|
||||
font-family: var(--font-sans);
|
||||
font-size: 0.72rem;
|
||||
font-variant-caps: normal;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: 0.03em;
|
||||
color: var(--text-muted);
|
||||
border: 1px solid var(--border-muted);
|
||||
border-radius: 2px;
|
||||
padding: 0.05em 0.5em;
|
||||
margin-right: 0.25em;
|
||||
}
|
||||
|
||||
details[open] > .ep-summary::before { content: "▾\00a0"; }
|
||||
|
||||
.ep-summary:hover { color: var(--text-muted); }
|
||||
|
||||
/* Definition list for expanded profile */
|
||||
.ep-expanded {
|
||||
display: grid;
|
||||
|
|
@ -894,24 +888,6 @@ details[open] > .ep-summary::before { content: "▾\00a0"; }
|
|||
}
|
||||
|
||||
|
||||
/* Overall score percentage in the top metadata nav (adjacent to Epistemic link).
|
||||
Renders as a compact numeric chip: "72%" in small-caps sans, separated from
|
||||
the link text by a faint centerdot. */
|
||||
.meta-overall-score {
|
||||
font-family: var(--font-sans);
|
||||
font-size: 0.68rem;
|
||||
font-variant-numeric: tabular-nums;
|
||||
letter-spacing: 0.03em;
|
||||
color: var(--text-muted);
|
||||
display: inline-block;
|
||||
text-decoration: none;
|
||||
border: 1px solid var(--border-muted);
|
||||
border-radius: 2px;
|
||||
padding: 0.05em 0.5em;
|
||||
margin-left: 0.5em;
|
||||
vertical-align: 0.05em;
|
||||
}
|
||||
|
||||
/* ============================================================
|
||||
PAGINATION NAV
|
||||
============================================================ */
|
||||
|
|
|
|||
|
|
@ -641,9 +641,12 @@
|
|||
return html;
|
||||
}
|
||||
|
||||
/* Epistemic jump link — reads the #epistemic section already in the DOM
|
||||
and renders a compact summary: status/confidence/dots + expanded DL.
|
||||
All ep-* classes are already styled via components.css.
|
||||
/* Epistemic jump link — pulls the parallel-tag strip from the top of
|
||||
the page (which holds the author-declared orientation tags) and
|
||||
the expanded DL from the #epistemic footer section (which holds
|
||||
the git-derived stability/last-reviewed/trend). The popup combines
|
||||
both so a reader hovering the link mid-page sees the full profile
|
||||
without scrolling.
|
||||
|
||||
Returns a DocumentFragment instead of an HTML string so the popup
|
||||
receives cloned nodes (defense in depth — if a future change ever
|
||||
|
|
@ -651,25 +654,21 @@
|
|||
would still see exactly the same already-rendered DOM rather than
|
||||
a re-parsed string). */
|
||||
function epistemicContent() {
|
||||
var section = document.getElementById('epistemic');
|
||||
if (!section) return Promise.resolve(null);
|
||||
|
||||
var wrap = document.createElement('div');
|
||||
wrap.className = 'popup-epistemic';
|
||||
|
||||
var compact = section.querySelector('.ep-compact');
|
||||
if (compact) {
|
||||
var compactClone = compact.cloneNode(true);
|
||||
wrap.appendChild(compactClone);
|
||||
var strip = document.querySelector('.meta-epistemic-strip');
|
||||
if (strip) {
|
||||
wrap.appendChild(strip.cloneNode(true));
|
||||
}
|
||||
|
||||
var expanded = section.querySelector('.ep-expanded');
|
||||
var section = document.getElementById('epistemic');
|
||||
var expanded = section ? section.querySelector('.ep-expanded') : null;
|
||||
if (expanded) {
|
||||
var expandedClone = expanded.cloneNode(true);
|
||||
wrap.appendChild(expandedClone);
|
||||
wrap.appendChild(expanded.cloneNode(true));
|
||||
}
|
||||
|
||||
if (!compact && !expanded) return Promise.resolve(null);
|
||||
if (!strip && !expanded) return Promise.resolve(null);
|
||||
return Promise.resolve(wrap);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
<div class="library-controls-options" role="group" aria-label="Sort order">
|
||||
<button class="library-sort-btn" data-sort="date">date</button>
|
||||
<button class="library-sort-btn" data-sort="title">title</button>
|
||||
<button class="library-sort-btn" data-sort="score">epistemic effort</button>
|
||||
<button class="library-sort-btn" data-sort="score">trust</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,21 @@
|
|||
$for(affiliation-links)$$if(affiliation-url)$<a href="$affiliation-url$">$affiliation-name$</a>$else$$affiliation-name$$endif$$sep$ · $endfor$
|
||||
</div>
|
||||
$endif$
|
||||
$if(status)$
|
||||
<div class="meta-row meta-epistemic-strip" data-pagefind-ignore="all">
|
||||
$if(overall-score)$<span class="ep-trust" title="Trust score: $overall-score$/100 (confidence × 0.6 + evidence × 0.4)"><span class="ep-score">$overall-score$%</span> trust</span>$endif$
|
||||
<span class="ep-status">$status$</span>
|
||||
$if(confidence)$<span class="ep-row" title="Confidence">$confidence$% confidence</span>$endif$
|
||||
$if(importance-dots)$<span class="ep-row" title="Importance: $importance$/5"><span class="ep-dots">$importance-dots$</span> importance</span>$endif$
|
||||
$if(evidence-dots)$<span class="ep-row" title="Evidence quality: $evidence$/5"><span class="ep-dots">$evidence-dots$</span> evidence quality</span>$endif$
|
||||
$if(scope)$<span class="ep-row" title="Scope">$scope$ scope</span>$endif$
|
||||
$if(novelty)$<span class="ep-row" title="Novelty">$novelty$ novelty</span>$endif$
|
||||
$if(practicality)$<span class="ep-row" title="Practicality">$practicality$ practicality</span>$endif$
|
||||
</div>
|
||||
$endif$
|
||||
<nav class="meta-row meta-pagelinks" aria-label="Page sections">
|
||||
<a href="#version-history">History</a>
|
||||
$if(status)$<a href="#epistemic">$if(overall-score)$<span class="ep-link-label">Epistemic</span><span class="meta-overall-score" title="Overall score: $overall-score$/100">$overall-score$%</span>$else$Epistemic$endif$</a>$endif$
|
||||
$if(status)$<a href="#epistemic">Epistemic</a>$endif$
|
||||
$if(bibliography)$<a href="#bibliography">Bibliography</a>$endif$
|
||||
$if(backlinks)$<a href="#backlinks">Backlinks</a>$endif$
|
||||
$if(repository)$<a href="$repository$">Repository</a>$endif$
|
||||
|
|
|
|||
|
|
@ -35,23 +35,11 @@
|
|||
$if(status)$
|
||||
<div class="meta-footer-section meta-footer-epistemic" id="epistemic">
|
||||
<h3><a href="/colophon.html#living-documents">Epistemic</a></h3>
|
||||
<div class="ep-compact">
|
||||
<span class="ep-status">$status$</span>
|
||||
$if(confidence)$<span class="ep-confidence" title="Confidence">$confidence$%</span>$endif$
|
||||
$if(importance-dots)$<span class="ep-dots" title="Importance: $importance$/5">$importance-dots$</span>$endif$
|
||||
$if(evidence-dots)$<span class="ep-dots" title="Evidence quality: $evidence$/5">$evidence-dots$</span>$endif$
|
||||
</div>
|
||||
<details class="ep-details">
|
||||
<summary class="ep-summary">detail</summary>
|
||||
<dl class="ep-expanded">
|
||||
<dt>Stability</dt><dd>$stability$</dd>
|
||||
$if(scope)$<dt>Scope</dt><dd>$scope$</dd>$endif$
|
||||
$if(novelty)$<dt>Novelty</dt><dd>$novelty$</dd>$endif$
|
||||
$if(practicality)$<dt>Practicality</dt><dd>$practicality$</dd>$endif$
|
||||
$if(last-reviewed)$<dt>Last reviewed</dt><dd>$last-reviewed$</dd>$endif$
|
||||
$if(confidence-trend)$<dt>Confidence trend</dt><dd>$confidence-trend$</dd>$endif$
|
||||
</dl>
|
||||
</details>
|
||||
<dl class="ep-expanded">
|
||||
<dt>Stability</dt><dd>$stability$</dd>
|
||||
$if(last-reviewed)$<dt>Last reviewed</dt><dd>$last-reviewed$</dd>$endif$
|
||||
$if(confidence-trend)$<dt>Confidence trend</dt><dd>$confidence-trend$</dd>$endif$
|
||||
</dl>
|
||||
</div>
|
||||
$endif$
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue