chore: renormalize line endings under the new .gitattributes
Line-ending only. Verified: 3667 insertions against 3667 deletions with zero content difference under --ignore-cr-at-eol.
This commit is contained in:
1202
.obsidian/plugins/webinar-dash/main.js
vendored
1202
.obsidian/plugins/webinar-dash/main.js
vendored
File diff suppressed because it is too large
Load Diff
18
.obsidian/plugins/webinar-dash/manifest.json
vendored
18
.obsidian/plugins/webinar-dash/manifest.json
vendored
@@ -1,9 +1,9 @@
|
||||
{
|
||||
"id": "webinar-dash",
|
||||
"name": "Webinar dashboard",
|
||||
"version": "0.1.0",
|
||||
"minAppVersion": "1.5.0",
|
||||
"description": "Source pipeline and script coverage for the webinar vault.",
|
||||
"author": "meels",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
{
|
||||
"id": "webinar-dash",
|
||||
"name": "Webinar dashboard",
|
||||
"version": "0.1.0",
|
||||
"minAppVersion": "1.5.0",
|
||||
"description": "Source pipeline and script coverage for the webinar vault.",
|
||||
"author": "meels",
|
||||
"isDesktopOnly": true
|
||||
}
|
||||
|
||||
478
.obsidian/plugins/webinar-dash/styles.css
vendored
478
.obsidian/plugins/webinar-dash/styles.css
vendored
@@ -1,239 +1,239 @@
|
||||
.webinar-dash {
|
||||
--wd-ink-000: #ffffff; --wd-ink-050: #f7f7f7; --wd-ink-100: #ececec;
|
||||
--wd-ink-200: #d9d9d9; --wd-ink-400: #8a8a8a; --wd-ink-500: #5e5e5e;
|
||||
--wd-ink-700: #262626; --wd-ink-900: #0a0a0a; --wd-ink-999: #000000;
|
||||
--wd-red-500: #e1261c; --wd-red-600: #c31c14;
|
||||
|
||||
--wd-bg: var(--wd-ink-000);
|
||||
--wd-bg-subtle: var(--wd-ink-050);
|
||||
--wd-fg: var(--wd-ink-999);
|
||||
--wd-fg-2: var(--wd-ink-700);
|
||||
--wd-fg-3: var(--wd-ink-500);
|
||||
--wd-fg-4: var(--wd-ink-400);
|
||||
--wd-border: var(--wd-ink-200);
|
||||
--wd-border-strong: var(--wd-ink-999);
|
||||
--wd-border-subtle: var(--wd-ink-100);
|
||||
--wd-accent: var(--wd-red-500);
|
||||
--wd-accent-press: var(--wd-red-600);
|
||||
--wd-accent-on: #ffffff;
|
||||
--wd-ok: #0a8a3f;
|
||||
--wd-warn: #c68a00;
|
||||
--wd-danger: var(--wd-red-500);
|
||||
|
||||
--wd-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
--wd-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
|
||||
|
||||
font-family: var(--wd-sans);
|
||||
color: var(--wd-fg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
/* Past roughly this width the two panes stop reading as a pair and table
|
||||
rows get hard to track across. Cap the whole dashboard, not just the
|
||||
grid, so the toolbar stays flush with the panes below it. */
|
||||
max-width: 1600px;
|
||||
/* Makes this element the reference for the @container query further down,
|
||||
so the grid collapses on the pane's width rather than the window's. */
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.theme-dark .webinar-dash {
|
||||
--wd-bg: var(--wd-ink-900);
|
||||
--wd-bg-subtle: #161616;
|
||||
--wd-fg: var(--wd-ink-000);
|
||||
--wd-fg-2: var(--wd-ink-200);
|
||||
--wd-fg-3: var(--wd-ink-400);
|
||||
--wd-fg-4: var(--wd-ink-500);
|
||||
--wd-border: var(--wd-ink-700);
|
||||
--wd-border-strong: #b8b8b8;
|
||||
--wd-border-subtle: #161616;
|
||||
/* Accent tracks the installed theme at .obsidian/themes/tesanti/theme.css,
|
||||
whose dark section reads "Black canvas, same signal red": --accent-h/-s/-l
|
||||
are declared once at :root and never redeclared under .theme-dark, and only
|
||||
the hover state lifts (#c31c14 light, #ff4d43 dark). Match that exactly. */
|
||||
--wd-accent: var(--wd-red-500);
|
||||
--wd-accent-press: #ff4d43;
|
||||
--wd-accent-on: #ffffff;
|
||||
/* Status tokens are separate from the brand accent by design-system rule, and
|
||||
here they carry small text in a dense table. #e1261c on near-black is about
|
||||
3.8:1, under AA for small text, so these lift where the accent does not. */
|
||||
--wd-ok: #2fbf6a;
|
||||
--wd-warn: #e0a516;
|
||||
--wd-danger: #ff5c50;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
Escape Obsidian's readable-line-length cap.
|
||||
|
||||
With "Readable line length" on (the default), Obsidian caps note
|
||||
content at --file-line-width, roughly 700px. That is right for prose
|
||||
and wrong for a two-pane dashboard, which gets squeezed into a column.
|
||||
|
||||
:has() scopes this to the sizer that actually contains a dashboard, so
|
||||
every other note in the vault keeps its readable width. Both selectors
|
||||
are needed: reading view sizes on .markdown-preview-sizer, live preview
|
||||
on .cm-sizer.
|
||||
|
||||
If you would rather not rely on this, the alternatives are Settings ->
|
||||
Editor -> Readable line length (off, but that widens every note), or
|
||||
adding `cssclasses: wide-dash` to the note's frontmatter and swapping
|
||||
the :has() selectors below for `.wide-dash .markdown-preview-sizer`.
|
||||
------------------------------------------------------------------ */
|
||||
.markdown-preview-sizer:has(.webinar-dash),
|
||||
.markdown-source-view.mod-cm6 .cm-sizer:has(.webinar-dash) {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.wd-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 38fr) minmax(0, 62fr);
|
||||
gap: 24px;
|
||||
}
|
||||
.wd-grid > * { min-width: 0; }
|
||||
|
||||
.wd-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
border: 1px solid var(--wd-border);
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
background: var(--wd-bg-subtle);
|
||||
}
|
||||
|
||||
.wd-btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--wd-fg);
|
||||
border-color: var(--wd-border-strong);
|
||||
}
|
||||
.wd-btn-ghost:hover {
|
||||
background: var(--wd-bg-muted, var(--wd-bg-subtle));
|
||||
border-color: var(--wd-border-strong);
|
||||
}
|
||||
|
||||
/* Collapse to one column on the width that actually matters — the pane's,
|
||||
not the window's. A media query measures the window, so a wide window
|
||||
with the dashboard in a narrow split pane would keep two cramped
|
||||
columns. The container query below responds to the pane itself; the
|
||||
media query stays as a floor for a genuinely narrow window. */
|
||||
@container (max-width: 820px) {
|
||||
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
.wd-pane { display: flex; flex-direction: column; gap: 20px; }
|
||||
|
||||
.wd-eyebrow {
|
||||
font-family: var(--wd-mono); font-size: 11px; line-height: 1;
|
||||
letter-spacing: 0.12em; text-transform: uppercase;
|
||||
color: var(--wd-fg-3); font-weight: 500;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.wd-eyebrow::before {
|
||||
content: ""; width: 5px; height: 5px; flex: none; background: var(--wd-accent);
|
||||
}
|
||||
|
||||
.wd-block { display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
.wd-row {
|
||||
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
|
||||
border: 1px solid var(--wd-border); border-radius: 4px;
|
||||
padding: 12px 12px 12px 16px; background: var(--wd-bg);
|
||||
}
|
||||
.wd-row + .wd-row { margin-top: -1px; }
|
||||
.wd-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
||||
.wd-row-name {
|
||||
font-size: 14px; font-weight: 600;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
.wd-mono {
|
||||
font-family: var(--wd-mono); font-size: 11px; color: var(--wd-fg-3);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wd-btn {
|
||||
display: inline-flex; align-items: center; gap: 6px; flex: none;
|
||||
font-family: var(--wd-sans); font-size: 13px; font-weight: 600;
|
||||
padding: 6px 12px; border-radius: 6px; cursor: pointer;
|
||||
border: 1px solid var(--wd-accent); background: var(--wd-accent);
|
||||
color: var(--wd-accent-on);
|
||||
transition: background 120ms cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
.wd-btn:hover { background: var(--wd-accent-press); border-color: var(--wd-accent-press); }
|
||||
.wd-btn:focus-visible { outline: 2px solid var(--wd-accent); outline-offset: 2px; }
|
||||
.wd-btn[disabled] {
|
||||
opacity: 0.45; cursor: not-allowed;
|
||||
background: transparent; color: var(--wd-fg-3); border-color: var(--wd-border);
|
||||
}
|
||||
.wd-btn svg { width: 14px; height: 14px; flex: none; }
|
||||
|
||||
.wd-done { display: flex; flex-direction: column; }
|
||||
.wd-done-row {
|
||||
display: flex; align-items: baseline; gap: 12px; padding: 5px 0;
|
||||
border-bottom: 1px solid var(--wd-border-subtle); font-size: 13px;
|
||||
}
|
||||
.wd-done-row:last-child { border-bottom: 0; }
|
||||
.wd-done-name {
|
||||
color: var(--wd-fg-2);
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
|
||||
.wd-note { font-size: 12px; color: var(--wd-fg-3); }
|
||||
.wd-error {
|
||||
font-size: 13px; color: var(--wd-danger);
|
||||
border: 1px solid var(--wd-danger); border-radius: 4px; padding: 12px;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.webinar-dash * { transition-duration: 0.01ms !important; }
|
||||
}
|
||||
|
||||
.wd-meter { display: flex; gap: 2px; height: 8px; width: 100%; }
|
||||
.wd-meter > i { display: block; height: 100%; }
|
||||
.wd-seg-covered { background: var(--wd-ok); }
|
||||
.wd-seg-partial { background: var(--wd-warn); }
|
||||
.wd-seg-absent { background: var(--wd-danger); }
|
||||
|
||||
.wd-key { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: var(--wd-fg-2); }
|
||||
.wd-key > span { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.wd-key i { width: 8px; height: 8px; flex: none; }
|
||||
|
||||
.wd-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.wd-tbl th {
|
||||
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
||||
text-transform: uppercase; color: var(--wd-fg-3); font-weight: 500;
|
||||
text-align: left; padding: 0 12px 8px 0;
|
||||
border-bottom: 1px solid var(--wd-border-strong);
|
||||
}
|
||||
.wd-tbl td {
|
||||
padding: 6px 12px 6px 0; border-bottom: 1px solid var(--wd-border-subtle);
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.wd-grp td {
|
||||
padding-top: 16px; border-bottom: 1px solid var(--wd-border-strong);
|
||||
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
||||
text-transform: uppercase; color: var(--wd-fg); font-weight: 500;
|
||||
}
|
||||
.wd-stat { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; }
|
||||
.wd-stat svg { width: 13px; height: 13px; flex: none; }
|
||||
.wd-covered { color: var(--wd-ok); }
|
||||
.wd-partial { color: var(--wd-warn); }
|
||||
.wd-absent { color: var(--wd-danger); }
|
||||
.wd-pin { font-family: var(--wd-mono); font-size: 10px; color: var(--wd-fg-4); }
|
||||
|
||||
.wd-status { font-family: var(--wd-mono); font-size: 11px; flex: none; }
|
||||
.wd-status-running { color: var(--wd-warn); }
|
||||
.wd-status-done { color: var(--wd-ok); }
|
||||
.wd-status-failed { color: var(--wd-danger); }
|
||||
.wd-output {
|
||||
flex-basis: 100%;
|
||||
width: 100%;
|
||||
font-family: var(--wd-mono); font-size: 11px; white-space: pre-wrap;
|
||||
max-height: 220px; overflow: auto; margin-top: 8px;
|
||||
border: 1px solid var(--wd-border); border-radius: 4px; padding: 8px;
|
||||
color: var(--wd-fg-2);
|
||||
}
|
||||
.webinar-dash {
|
||||
--wd-ink-000: #ffffff; --wd-ink-050: #f7f7f7; --wd-ink-100: #ececec;
|
||||
--wd-ink-200: #d9d9d9; --wd-ink-400: #8a8a8a; --wd-ink-500: #5e5e5e;
|
||||
--wd-ink-700: #262626; --wd-ink-900: #0a0a0a; --wd-ink-999: #000000;
|
||||
--wd-red-500: #e1261c; --wd-red-600: #c31c14;
|
||||
|
||||
--wd-bg: var(--wd-ink-000);
|
||||
--wd-bg-subtle: var(--wd-ink-050);
|
||||
--wd-fg: var(--wd-ink-999);
|
||||
--wd-fg-2: var(--wd-ink-700);
|
||||
--wd-fg-3: var(--wd-ink-500);
|
||||
--wd-fg-4: var(--wd-ink-400);
|
||||
--wd-border: var(--wd-ink-200);
|
||||
--wd-border-strong: var(--wd-ink-999);
|
||||
--wd-border-subtle: var(--wd-ink-100);
|
||||
--wd-accent: var(--wd-red-500);
|
||||
--wd-accent-press: var(--wd-red-600);
|
||||
--wd-accent-on: #ffffff;
|
||||
--wd-ok: #0a8a3f;
|
||||
--wd-warn: #c68a00;
|
||||
--wd-danger: var(--wd-red-500);
|
||||
|
||||
--wd-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
|
||||
--wd-sans: "Inter", ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif;
|
||||
|
||||
font-family: var(--wd-sans);
|
||||
color: var(--wd-fg);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 16px;
|
||||
/* Past roughly this width the two panes stop reading as a pair and table
|
||||
rows get hard to track across. Cap the whole dashboard, not just the
|
||||
grid, so the toolbar stays flush with the panes below it. */
|
||||
max-width: 1600px;
|
||||
/* Makes this element the reference for the @container query further down,
|
||||
so the grid collapses on the pane's width rather than the window's. */
|
||||
container-type: inline-size;
|
||||
}
|
||||
|
||||
.theme-dark .webinar-dash {
|
||||
--wd-bg: var(--wd-ink-900);
|
||||
--wd-bg-subtle: #161616;
|
||||
--wd-fg: var(--wd-ink-000);
|
||||
--wd-fg-2: var(--wd-ink-200);
|
||||
--wd-fg-3: var(--wd-ink-400);
|
||||
--wd-fg-4: var(--wd-ink-500);
|
||||
--wd-border: var(--wd-ink-700);
|
||||
--wd-border-strong: #b8b8b8;
|
||||
--wd-border-subtle: #161616;
|
||||
/* Accent tracks the installed theme at .obsidian/themes/tesanti/theme.css,
|
||||
whose dark section reads "Black canvas, same signal red": --accent-h/-s/-l
|
||||
are declared once at :root and never redeclared under .theme-dark, and only
|
||||
the hover state lifts (#c31c14 light, #ff4d43 dark). Match that exactly. */
|
||||
--wd-accent: var(--wd-red-500);
|
||||
--wd-accent-press: #ff4d43;
|
||||
--wd-accent-on: #ffffff;
|
||||
/* Status tokens are separate from the brand accent by design-system rule, and
|
||||
here they carry small text in a dense table. #e1261c on near-black is about
|
||||
3.8:1, under AA for small text, so these lift where the accent does not. */
|
||||
--wd-ok: #2fbf6a;
|
||||
--wd-warn: #e0a516;
|
||||
--wd-danger: #ff5c50;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------
|
||||
Escape Obsidian's readable-line-length cap.
|
||||
|
||||
With "Readable line length" on (the default), Obsidian caps note
|
||||
content at --file-line-width, roughly 700px. That is right for prose
|
||||
and wrong for a two-pane dashboard, which gets squeezed into a column.
|
||||
|
||||
:has() scopes this to the sizer that actually contains a dashboard, so
|
||||
every other note in the vault keeps its readable width. Both selectors
|
||||
are needed: reading view sizes on .markdown-preview-sizer, live preview
|
||||
on .cm-sizer.
|
||||
|
||||
If you would rather not rely on this, the alternatives are Settings ->
|
||||
Editor -> Readable line length (off, but that widens every note), or
|
||||
adding `cssclasses: wide-dash` to the note's frontmatter and swapping
|
||||
the :has() selectors below for `.wide-dash .markdown-preview-sizer`.
|
||||
------------------------------------------------------------------ */
|
||||
.markdown-preview-sizer:has(.webinar-dash),
|
||||
.markdown-source-view.mod-cm6 .cm-sizer:has(.webinar-dash) {
|
||||
max-width: none;
|
||||
}
|
||||
|
||||
.wd-grid {
|
||||
display: grid;
|
||||
grid-template-columns: minmax(0, 38fr) minmax(0, 62fr);
|
||||
gap: 24px;
|
||||
}
|
||||
.wd-grid > * { min-width: 0; }
|
||||
|
||||
.wd-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
flex-wrap: wrap;
|
||||
border: 1px solid var(--wd-border);
|
||||
border-radius: 4px;
|
||||
padding: 8px 12px;
|
||||
background: var(--wd-bg-subtle);
|
||||
}
|
||||
|
||||
.wd-btn-ghost {
|
||||
background: transparent;
|
||||
color: var(--wd-fg);
|
||||
border-color: var(--wd-border-strong);
|
||||
}
|
||||
.wd-btn-ghost:hover {
|
||||
background: var(--wd-bg-muted, var(--wd-bg-subtle));
|
||||
border-color: var(--wd-border-strong);
|
||||
}
|
||||
|
||||
/* Collapse to one column on the width that actually matters — the pane's,
|
||||
not the window's. A media query measures the window, so a wide window
|
||||
with the dashboard in a narrow split pane would keep two cramped
|
||||
columns. The container query below responds to the pane itself; the
|
||||
media query stays as a floor for a genuinely narrow window. */
|
||||
@container (max-width: 820px) {
|
||||
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
@media (max-width: 820px) {
|
||||
.wd-grid { grid-template-columns: minmax(0, 1fr); }
|
||||
}
|
||||
|
||||
.wd-pane { display: flex; flex-direction: column; gap: 20px; }
|
||||
|
||||
.wd-eyebrow {
|
||||
font-family: var(--wd-mono); font-size: 11px; line-height: 1;
|
||||
letter-spacing: 0.12em; text-transform: uppercase;
|
||||
color: var(--wd-fg-3); font-weight: 500;
|
||||
display: flex; align-items: center; gap: 8px;
|
||||
}
|
||||
.wd-eyebrow::before {
|
||||
content: ""; width: 5px; height: 5px; flex: none; background: var(--wd-accent);
|
||||
}
|
||||
|
||||
.wd-block { display: flex; flex-direction: column; gap: 12px; }
|
||||
|
||||
.wd-row {
|
||||
display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
|
||||
border: 1px solid var(--wd-border); border-radius: 4px;
|
||||
padding: 12px 12px 12px 16px; background: var(--wd-bg);
|
||||
}
|
||||
.wd-row + .wd-row { margin-top: -1px; }
|
||||
.wd-row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
|
||||
.wd-row-name {
|
||||
font-size: 14px; font-weight: 600;
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
.wd-mono {
|
||||
font-family: var(--wd-mono); font-size: 11px; color: var(--wd-fg-3);
|
||||
font-variant-numeric: tabular-nums;
|
||||
}
|
||||
|
||||
.wd-btn {
|
||||
display: inline-flex; align-items: center; gap: 6px; flex: none;
|
||||
font-family: var(--wd-sans); font-size: 13px; font-weight: 600;
|
||||
padding: 6px 12px; border-radius: 6px; cursor: pointer;
|
||||
border: 1px solid var(--wd-accent); background: var(--wd-accent);
|
||||
color: var(--wd-accent-on);
|
||||
transition: background 120ms cubic-bezier(0.2, 0, 0, 1);
|
||||
}
|
||||
.wd-btn:hover { background: var(--wd-accent-press); border-color: var(--wd-accent-press); }
|
||||
.wd-btn:focus-visible { outline: 2px solid var(--wd-accent); outline-offset: 2px; }
|
||||
.wd-btn[disabled] {
|
||||
opacity: 0.45; cursor: not-allowed;
|
||||
background: transparent; color: var(--wd-fg-3); border-color: var(--wd-border);
|
||||
}
|
||||
.wd-btn svg { width: 14px; height: 14px; flex: none; }
|
||||
|
||||
.wd-done { display: flex; flex-direction: column; }
|
||||
.wd-done-row {
|
||||
display: flex; align-items: baseline; gap: 12px; padding: 5px 0;
|
||||
border-bottom: 1px solid var(--wd-border-subtle); font-size: 13px;
|
||||
}
|
||||
.wd-done-row:last-child { border-bottom: 0; }
|
||||
.wd-done-name {
|
||||
color: var(--wd-fg-2);
|
||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||
}
|
||||
|
||||
.wd-note { font-size: 12px; color: var(--wd-fg-3); }
|
||||
.wd-error {
|
||||
font-size: 13px; color: var(--wd-danger);
|
||||
border: 1px solid var(--wd-danger); border-radius: 4px; padding: 12px;
|
||||
}
|
||||
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.webinar-dash * { transition-duration: 0.01ms !important; }
|
||||
}
|
||||
|
||||
.wd-meter { display: flex; gap: 2px; height: 8px; width: 100%; }
|
||||
.wd-meter > i { display: block; height: 100%; }
|
||||
.wd-seg-covered { background: var(--wd-ok); }
|
||||
.wd-seg-partial { background: var(--wd-warn); }
|
||||
.wd-seg-absent { background: var(--wd-danger); }
|
||||
|
||||
.wd-key { display: flex; flex-wrap: wrap; gap: 16px; font-size: 12px; color: var(--wd-fg-2); }
|
||||
.wd-key > span { display: inline-flex; align-items: center; gap: 6px; }
|
||||
.wd-key i { width: 8px; height: 8px; flex: none; }
|
||||
|
||||
.wd-tbl { width: 100%; border-collapse: collapse; font-size: 13px; }
|
||||
.wd-tbl th {
|
||||
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
||||
text-transform: uppercase; color: var(--wd-fg-3); font-weight: 500;
|
||||
text-align: left; padding: 0 12px 8px 0;
|
||||
border-bottom: 1px solid var(--wd-border-strong);
|
||||
}
|
||||
.wd-tbl td {
|
||||
padding: 6px 12px 6px 0; border-bottom: 1px solid var(--wd-border-subtle);
|
||||
vertical-align: baseline;
|
||||
}
|
||||
.wd-grp td {
|
||||
padding-top: 16px; border-bottom: 1px solid var(--wd-border-strong);
|
||||
font-family: var(--wd-mono); font-size: 10px; letter-spacing: 0.1em;
|
||||
text-transform: uppercase; color: var(--wd-fg); font-weight: 500;
|
||||
}
|
||||
.wd-stat { display: inline-flex; align-items: center; gap: 5px; font-size: 12px; font-weight: 600; }
|
||||
.wd-stat svg { width: 13px; height: 13px; flex: none; }
|
||||
.wd-covered { color: var(--wd-ok); }
|
||||
.wd-partial { color: var(--wd-warn); }
|
||||
.wd-absent { color: var(--wd-danger); }
|
||||
.wd-pin { font-family: var(--wd-mono); font-size: 10px; color: var(--wd-fg-4); }
|
||||
|
||||
.wd-status { font-family: var(--wd-mono); font-size: 11px; flex: none; }
|
||||
.wd-status-running { color: var(--wd-warn); }
|
||||
.wd-status-done { color: var(--wd-ok); }
|
||||
.wd-status-failed { color: var(--wd-danger); }
|
||||
.wd-output {
|
||||
flex-basis: 100%;
|
||||
width: 100%;
|
||||
font-family: var(--wd-mono); font-size: 11px; white-space: pre-wrap;
|
||||
max-height: 220px; overflow: auto; margin-top: 8px;
|
||||
border: 1px solid var(--wd-border); border-radius: 4px; padding: 8px;
|
||||
color: var(--wd-fg-2);
|
||||
}
|
||||
|
||||
244
.obsidian/plugins/webinar-dash/test/coverage.test.js
vendored
244
.obsidian/plugins/webinar-dash/test/coverage.test.js
vendored
@@ -1,122 +1,122 @@
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { parseCoverageTable, groupByStation } = require("../main.js").__test__;
|
||||
|
||||
const DOC = [
|
||||
"# Script coverage",
|
||||
"",
|
||||
"#coverage",
|
||||
"",
|
||||
"## Metadata",
|
||||
"",
|
||||
"- **Script:** `raw/sources/Webinar script.md`",
|
||||
"- **Last synced:** 2026-07-28",
|
||||
"",
|
||||
"## Coverage",
|
||||
"",
|
||||
"| Concept | Status | Station | Pinned |",
|
||||
"|---|---|---|---|",
|
||||
"| [[harness]] | covered | Tools | |",
|
||||
"| [[agentic-loops]] | partial | Process | |",
|
||||
"| [[levels-of-ai-usage]] | partial | all | |",
|
||||
"| [[connections-as-moat]] | absent | — | yes |",
|
||||
].join("\n");
|
||||
|
||||
test("parseCoverageTable reads metadata", () => {
|
||||
const { meta } = parseCoverageTable(DOC);
|
||||
assert.equal(meta.script, "raw/sources/Webinar script.md");
|
||||
assert.equal(meta.lastSynced, "2026-07-28");
|
||||
});
|
||||
|
||||
test("parseCoverageTable reads every data row and skips the header", () => {
|
||||
const { rows, errors } = parseCoverageTable(DOC);
|
||||
assert.equal(errors.length, 0);
|
||||
assert.equal(rows.length, 4);
|
||||
assert.deepEqual(rows.map((r) => r.concept), [
|
||||
"harness", "agentic-loops", "levels-of-ai-usage", "connections-as-moat",
|
||||
]);
|
||||
});
|
||||
|
||||
test("parseCoverageTable normalises stations", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
assert.deepEqual(rows[0].stations, ["Tools"]);
|
||||
assert.deepEqual(rows[2].stations, ["all"]);
|
||||
assert.deepEqual(rows[3].stations, []);
|
||||
});
|
||||
|
||||
test("parseCoverageTable reads the pinned flag", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
assert.equal(rows[0].pinned, false);
|
||||
assert.equal(rows[3].pinned, true);
|
||||
});
|
||||
|
||||
test("parseCoverageTable strips a wikilink alias", () => {
|
||||
const doc = "| Concept | Status | Station |\n|---|---|---|\n| [[harness\\|The harness]] | covered | Tools |";
|
||||
const { rows } = parseCoverageTable(doc);
|
||||
assert.equal(rows[0].concept, "harness");
|
||||
});
|
||||
|
||||
test("parseCoverageTable splits a multi-station cell", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered | Tools, Memory |";
|
||||
const { rows } = parseCoverageTable(doc);
|
||||
assert.deepEqual(rows[0].stations, ["Tools", "Memory"]);
|
||||
});
|
||||
|
||||
test("parseCoverageTable rejects an invalid status instead of coercing it", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | maybe | Tools |";
|
||||
const { rows, errors } = parseCoverageTable(doc);
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 1);
|
||||
assert.match(errors[0].reason, /invalid status/);
|
||||
assert.equal(errors[0].line, 3);
|
||||
});
|
||||
|
||||
test("parseCoverageTable reports a row with too few columns", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered |";
|
||||
const { rows, errors } = parseCoverageTable(doc);
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 1);
|
||||
assert.match(errors[0].reason, /at least 3 columns/);
|
||||
});
|
||||
|
||||
test("parseCoverageTable returns empty results for a document with no table", () => {
|
||||
const { rows, errors } = parseCoverageTable("# Nothing\n\nJust prose.");
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 0);
|
||||
});
|
||||
|
||||
test("groupByStation orders all-stations first and no-station last", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
const groups = groupByStation(rows);
|
||||
assert.deepEqual(groups.map((g) => g.station), [
|
||||
"All stations", "Tools", "Process", "No station",
|
||||
]);
|
||||
assert.equal(groups[1].rows[0].concept, "harness");
|
||||
});
|
||||
|
||||
test("groupByStation places a multi-station row under its first station only", () => {
|
||||
const rows = [{ concept: "x", status: "covered", stations: ["Memory", "Skills"], pinned: false, line: 1 }];
|
||||
const groups = groupByStation(rows);
|
||||
assert.equal(groups.length, 1);
|
||||
assert.equal(groups[0].station, "Memory");
|
||||
});
|
||||
|
||||
const { reconcileConcepts } = require("../main.js").__test__;
|
||||
|
||||
test("reconcileConcepts finds concept pages with no row", () => {
|
||||
const rows = [{ concept: "harness", status: "covered", stations: ["Tools"], pinned: false, line: 1 }];
|
||||
const out = reconcileConcepts(rows, ["harness", "brand-new-concept"]);
|
||||
assert.deepEqual(out.unsynced, ["brand-new-concept"]);
|
||||
assert.deepEqual(out.stale, []);
|
||||
});
|
||||
|
||||
test("reconcileConcepts finds rows whose concept page is gone", () => {
|
||||
const rows = [
|
||||
{ concept: "harness", status: "covered", stations: ["Tools"], pinned: false, line: 1 },
|
||||
{ concept: "deleted-idea", status: "absent", stations: [], pinned: false, line: 2 },
|
||||
];
|
||||
const out = reconcileConcepts(rows, ["harness"]);
|
||||
assert.deepEqual(out.stale.map((r) => r.concept), ["deleted-idea"]);
|
||||
assert.deepEqual(out.unsynced, []);
|
||||
});
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { parseCoverageTable, groupByStation } = require("../main.js").__test__;
|
||||
|
||||
const DOC = [
|
||||
"# Script coverage",
|
||||
"",
|
||||
"#coverage",
|
||||
"",
|
||||
"## Metadata",
|
||||
"",
|
||||
"- **Script:** `raw/sources/Webinar script.md`",
|
||||
"- **Last synced:** 2026-07-28",
|
||||
"",
|
||||
"## Coverage",
|
||||
"",
|
||||
"| Concept | Status | Station | Pinned |",
|
||||
"|---|---|---|---|",
|
||||
"| [[harness]] | covered | Tools | |",
|
||||
"| [[agentic-loops]] | partial | Process | |",
|
||||
"| [[levels-of-ai-usage]] | partial | all | |",
|
||||
"| [[connections-as-moat]] | absent | — | yes |",
|
||||
].join("\n");
|
||||
|
||||
test("parseCoverageTable reads metadata", () => {
|
||||
const { meta } = parseCoverageTable(DOC);
|
||||
assert.equal(meta.script, "raw/sources/Webinar script.md");
|
||||
assert.equal(meta.lastSynced, "2026-07-28");
|
||||
});
|
||||
|
||||
test("parseCoverageTable reads every data row and skips the header", () => {
|
||||
const { rows, errors } = parseCoverageTable(DOC);
|
||||
assert.equal(errors.length, 0);
|
||||
assert.equal(rows.length, 4);
|
||||
assert.deepEqual(rows.map((r) => r.concept), [
|
||||
"harness", "agentic-loops", "levels-of-ai-usage", "connections-as-moat",
|
||||
]);
|
||||
});
|
||||
|
||||
test("parseCoverageTable normalises stations", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
assert.deepEqual(rows[0].stations, ["Tools"]);
|
||||
assert.deepEqual(rows[2].stations, ["all"]);
|
||||
assert.deepEqual(rows[3].stations, []);
|
||||
});
|
||||
|
||||
test("parseCoverageTable reads the pinned flag", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
assert.equal(rows[0].pinned, false);
|
||||
assert.equal(rows[3].pinned, true);
|
||||
});
|
||||
|
||||
test("parseCoverageTable strips a wikilink alias", () => {
|
||||
const doc = "| Concept | Status | Station |\n|---|---|---|\n| [[harness\\|The harness]] | covered | Tools |";
|
||||
const { rows } = parseCoverageTable(doc);
|
||||
assert.equal(rows[0].concept, "harness");
|
||||
});
|
||||
|
||||
test("parseCoverageTable splits a multi-station cell", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered | Tools, Memory |";
|
||||
const { rows } = parseCoverageTable(doc);
|
||||
assert.deepEqual(rows[0].stations, ["Tools", "Memory"]);
|
||||
});
|
||||
|
||||
test("parseCoverageTable rejects an invalid status instead of coercing it", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | maybe | Tools |";
|
||||
const { rows, errors } = parseCoverageTable(doc);
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 1);
|
||||
assert.match(errors[0].reason, /invalid status/);
|
||||
assert.equal(errors[0].line, 3);
|
||||
});
|
||||
|
||||
test("parseCoverageTable reports a row with too few columns", () => {
|
||||
const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered |";
|
||||
const { rows, errors } = parseCoverageTable(doc);
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 1);
|
||||
assert.match(errors[0].reason, /at least 3 columns/);
|
||||
});
|
||||
|
||||
test("parseCoverageTable returns empty results for a document with no table", () => {
|
||||
const { rows, errors } = parseCoverageTable("# Nothing\n\nJust prose.");
|
||||
assert.equal(rows.length, 0);
|
||||
assert.equal(errors.length, 0);
|
||||
});
|
||||
|
||||
test("groupByStation orders all-stations first and no-station last", () => {
|
||||
const { rows } = parseCoverageTable(DOC);
|
||||
const groups = groupByStation(rows);
|
||||
assert.deepEqual(groups.map((g) => g.station), [
|
||||
"All stations", "Tools", "Process", "No station",
|
||||
]);
|
||||
assert.equal(groups[1].rows[0].concept, "harness");
|
||||
});
|
||||
|
||||
test("groupByStation places a multi-station row under its first station only", () => {
|
||||
const rows = [{ concept: "x", status: "covered", stations: ["Memory", "Skills"], pinned: false, line: 1 }];
|
||||
const groups = groupByStation(rows);
|
||||
assert.equal(groups.length, 1);
|
||||
assert.equal(groups[0].station, "Memory");
|
||||
});
|
||||
|
||||
const { reconcileConcepts } = require("../main.js").__test__;
|
||||
|
||||
test("reconcileConcepts finds concept pages with no row", () => {
|
||||
const rows = [{ concept: "harness", status: "covered", stations: ["Tools"], pinned: false, line: 1 }];
|
||||
const out = reconcileConcepts(rows, ["harness", "brand-new-concept"]);
|
||||
assert.deepEqual(out.unsynced, ["brand-new-concept"]);
|
||||
assert.deepEqual(out.stale, []);
|
||||
});
|
||||
|
||||
test("reconcileConcepts finds rows whose concept page is gone", () => {
|
||||
const rows = [
|
||||
{ concept: "harness", status: "covered", stations: ["Tools"], pinned: false, line: 1 },
|
||||
{ concept: "deleted-idea", status: "absent", stations: [], pinned: false, line: 2 },
|
||||
];
|
||||
const out = reconcileConcepts(rows, ["harness"]);
|
||||
assert.deepEqual(out.stale.map((r) => r.concept), ["deleted-idea"]);
|
||||
assert.deepEqual(out.unsynced, []);
|
||||
});
|
||||
|
||||
218
.obsidian/plugins/webinar-dash/test/pipeline.test.js
vendored
218
.obsidian/plugins/webinar-dash/test/pipeline.test.js
vendored
@@ -1,109 +1,109 @@
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { extractRawPath, derivePipeline } = require("../main.js").__test__;
|
||||
|
||||
test("extractRawPath pulls the backticked path", () => {
|
||||
const page = [
|
||||
"# You're reading way too much code",
|
||||
"",
|
||||
"#source",
|
||||
"",
|
||||
"## Source Metadata",
|
||||
"",
|
||||
"- **Date:** YouTube video, 24:11",
|
||||
"- **Raw path:** `raw/sources/You're reading way too much code.md`",
|
||||
"- **Source type:** video essay",
|
||||
].join("\n");
|
||||
assert.equal(extractRawPath(page), "raw/sources/You're reading way too much code.md");
|
||||
});
|
||||
|
||||
test("extractRawPath handles cyrillic and em dashes", () => {
|
||||
const page = "- **Raw path:** `raw/sources/Скиллы на базе git — новая память AI-агентов.md`";
|
||||
assert.equal(extractRawPath(page), "raw/sources/Скиллы на базе git — новая память AI-агентов.md");
|
||||
});
|
||||
|
||||
test("extractRawPath returns null when the line is absent", () => {
|
||||
assert.equal(extractRawPath("# A page\n\n#source\n\nNo metadata here."), null);
|
||||
});
|
||||
|
||||
test("derivePipeline splits claimed from unclaimed raw files", () => {
|
||||
const rawFiles = [
|
||||
{ path: "raw/sources/Nina interview.md", name: "Nina interview.md", size: 6614 },
|
||||
{ path: "raw/sources/Webinar script.md", name: "Webinar script.md", size: 15841 },
|
||||
];
|
||||
const sourcePages = [
|
||||
{
|
||||
path: "wiki/sources/2026-07-14-nina-interview.md",
|
||||
name: "2026-07-14-nina-interview.md",
|
||||
rawPath: "raw/sources/Nina interview.md",
|
||||
},
|
||||
];
|
||||
const out = derivePipeline({ rawFiles, sourcePages });
|
||||
assert.equal(out.processed.length, 1);
|
||||
assert.equal(out.processed[0].name, "Nina interview.md");
|
||||
assert.equal(out.processed[0].page.name, "2026-07-14-nina-interview.md");
|
||||
assert.equal(out.unprocessed.length, 1);
|
||||
assert.equal(out.unprocessed[0].name, "Webinar script.md");
|
||||
assert.equal(out.orphaned.length, 0);
|
||||
});
|
||||
|
||||
test("derivePipeline reports source pages whose raw file is gone", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/x.md", name: "x.md", rawPath: "raw/sources/deleted.md" },
|
||||
],
|
||||
});
|
||||
assert.equal(out.orphaned.length, 1);
|
||||
assert.equal(out.orphaned[0].name, "x.md");
|
||||
});
|
||||
|
||||
test("derivePipeline treats a page with no raw path as orphaned", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/a.md", name: "a.md", size: 10 }],
|
||||
sourcePages: [{ path: "wiki/sources/y.md", name: "y.md", rawPath: null }],
|
||||
});
|
||||
assert.equal(out.orphaned.length, 1);
|
||||
assert.equal(out.unprocessed.length, 1);
|
||||
});
|
||||
|
||||
test("derivePipeline routes a duplicate raw-path claim to orphaned", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/a.md", name: "a.md", size: 10 }],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/first.md", name: "first.md", rawPath: "raw/sources/a.md" },
|
||||
{ path: "wiki/sources/second.md", name: "second.md", rawPath: "raw/sources/a.md" },
|
||||
],
|
||||
});
|
||||
assert.equal(out.processed.length, 1);
|
||||
assert.equal(out.processed[0].page.name, "first.md");
|
||||
assert.equal(out.unprocessed.length, 0);
|
||||
assert.deepEqual(out.orphaned.map((p) => p.name), ["second.md"]);
|
||||
});
|
||||
|
||||
test("derivePipeline lists a page once when it is both a duplicate claim and missing its raw file", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/other.md", name: "other.md", size: 10 }],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/first.md", name: "first.md", rawPath: "raw/sources/gone.md" },
|
||||
{ path: "wiki/sources/second.md", name: "second.md", rawPath: "raw/sources/gone.md" },
|
||||
],
|
||||
});
|
||||
assert.deepEqual(out.orphaned.map((p) => p.name), ["first.md", "second.md"]);
|
||||
});
|
||||
|
||||
test("derivePipeline sorts unprocessed by name and processed newest first", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [
|
||||
{ path: "raw/sources/b.md", name: "b.md", size: 1 },
|
||||
{ path: "raw/sources/a.md", name: "a.md", size: 1 },
|
||||
{ path: "raw/sources/c.md", name: "c.md", size: 1 },
|
||||
],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/2026-07-14-x.md", name: "2026-07-14-x.md", rawPath: "raw/sources/c.md" },
|
||||
],
|
||||
});
|
||||
assert.deepEqual(out.unprocessed.map((f) => f.name), ["a.md", "b.md"]);
|
||||
assert.equal(out.processed.length, 1);
|
||||
});
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { extractRawPath, derivePipeline } = require("../main.js").__test__;
|
||||
|
||||
test("extractRawPath pulls the backticked path", () => {
|
||||
const page = [
|
||||
"# You're reading way too much code",
|
||||
"",
|
||||
"#source",
|
||||
"",
|
||||
"## Source Metadata",
|
||||
"",
|
||||
"- **Date:** YouTube video, 24:11",
|
||||
"- **Raw path:** `raw/sources/You're reading way too much code.md`",
|
||||
"- **Source type:** video essay",
|
||||
].join("\n");
|
||||
assert.equal(extractRawPath(page), "raw/sources/You're reading way too much code.md");
|
||||
});
|
||||
|
||||
test("extractRawPath handles cyrillic and em dashes", () => {
|
||||
const page = "- **Raw path:** `raw/sources/Скиллы на базе git — новая память AI-агентов.md`";
|
||||
assert.equal(extractRawPath(page), "raw/sources/Скиллы на базе git — новая память AI-агентов.md");
|
||||
});
|
||||
|
||||
test("extractRawPath returns null when the line is absent", () => {
|
||||
assert.equal(extractRawPath("# A page\n\n#source\n\nNo metadata here."), null);
|
||||
});
|
||||
|
||||
test("derivePipeline splits claimed from unclaimed raw files", () => {
|
||||
const rawFiles = [
|
||||
{ path: "raw/sources/Nina interview.md", name: "Nina interview.md", size: 6614 },
|
||||
{ path: "raw/sources/Webinar script.md", name: "Webinar script.md", size: 15841 },
|
||||
];
|
||||
const sourcePages = [
|
||||
{
|
||||
path: "wiki/sources/2026-07-14-nina-interview.md",
|
||||
name: "2026-07-14-nina-interview.md",
|
||||
rawPath: "raw/sources/Nina interview.md",
|
||||
},
|
||||
];
|
||||
const out = derivePipeline({ rawFiles, sourcePages });
|
||||
assert.equal(out.processed.length, 1);
|
||||
assert.equal(out.processed[0].name, "Nina interview.md");
|
||||
assert.equal(out.processed[0].page.name, "2026-07-14-nina-interview.md");
|
||||
assert.equal(out.unprocessed.length, 1);
|
||||
assert.equal(out.unprocessed[0].name, "Webinar script.md");
|
||||
assert.equal(out.orphaned.length, 0);
|
||||
});
|
||||
|
||||
test("derivePipeline reports source pages whose raw file is gone", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/x.md", name: "x.md", rawPath: "raw/sources/deleted.md" },
|
||||
],
|
||||
});
|
||||
assert.equal(out.orphaned.length, 1);
|
||||
assert.equal(out.orphaned[0].name, "x.md");
|
||||
});
|
||||
|
||||
test("derivePipeline treats a page with no raw path as orphaned", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/a.md", name: "a.md", size: 10 }],
|
||||
sourcePages: [{ path: "wiki/sources/y.md", name: "y.md", rawPath: null }],
|
||||
});
|
||||
assert.equal(out.orphaned.length, 1);
|
||||
assert.equal(out.unprocessed.length, 1);
|
||||
});
|
||||
|
||||
test("derivePipeline routes a duplicate raw-path claim to orphaned", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/a.md", name: "a.md", size: 10 }],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/first.md", name: "first.md", rawPath: "raw/sources/a.md" },
|
||||
{ path: "wiki/sources/second.md", name: "second.md", rawPath: "raw/sources/a.md" },
|
||||
],
|
||||
});
|
||||
assert.equal(out.processed.length, 1);
|
||||
assert.equal(out.processed[0].page.name, "first.md");
|
||||
assert.equal(out.unprocessed.length, 0);
|
||||
assert.deepEqual(out.orphaned.map((p) => p.name), ["second.md"]);
|
||||
});
|
||||
|
||||
test("derivePipeline lists a page once when it is both a duplicate claim and missing its raw file", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [{ path: "raw/sources/other.md", name: "other.md", size: 10 }],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/first.md", name: "first.md", rawPath: "raw/sources/gone.md" },
|
||||
{ path: "wiki/sources/second.md", name: "second.md", rawPath: "raw/sources/gone.md" },
|
||||
],
|
||||
});
|
||||
assert.deepEqual(out.orphaned.map((p) => p.name), ["first.md", "second.md"]);
|
||||
});
|
||||
|
||||
test("derivePipeline sorts unprocessed by name and processed newest first", () => {
|
||||
const out = derivePipeline({
|
||||
rawFiles: [
|
||||
{ path: "raw/sources/b.md", name: "b.md", size: 1 },
|
||||
{ path: "raw/sources/a.md", name: "a.md", size: 1 },
|
||||
{ path: "raw/sources/c.md", name: "c.md", size: 1 },
|
||||
],
|
||||
sourcePages: [
|
||||
{ path: "wiki/sources/2026-07-14-x.md", name: "2026-07-14-x.md", rawPath: "raw/sources/c.md" },
|
||||
],
|
||||
});
|
||||
assert.deepEqual(out.unprocessed.map((f) => f.name), ["a.md", "b.md"]);
|
||||
assert.equal(out.processed.length, 1);
|
||||
});
|
||||
|
||||
@@ -1,47 +1,47 @@
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { isSafeFilename } = require("../main.js").__test__;
|
||||
|
||||
test("isSafeFilename accepts every filename currently in the vault", () => {
|
||||
const real = [
|
||||
"Agentic Engineering, explained by a 10x developer.md",
|
||||
"Webinar Plan - From Chat Box to Your Own OS.md",
|
||||
"Webinar script.md",
|
||||
"You're reading way too much code.md",
|
||||
"ИИ глупый!.md",
|
||||
"Скиллы на базе git — новая память AI-агентов.md",
|
||||
"sebastian interview - conclusions and insights.md",
|
||||
"In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md",
|
||||
];
|
||||
for (const name of real) {
|
||||
assert.equal(isSafeFilename(name), true, `should accept: ${name}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects shell metacharacters", () => {
|
||||
for (const bad of ['a".md', "a`b.md", "a$b.md", "a&b.md", "a|b.md", "a;b.md",
|
||||
"a<b.md", "a>b.md", "a%b.md", "a\nb.md", "a\rb.md"]) {
|
||||
assert.equal(isSafeFilename(bad), false, `should reject: ${JSON.stringify(bad)}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects the cmd.exe escape character and control characters", () => {
|
||||
// `^` escapes the next character in cmd.exe, so it can defuse the closing
|
||||
// quote. NUL additionally makes spawn() throw synchronously.
|
||||
for (const bad of ["a^b.md", "a\u0000b.md", "a\u001bb.md", "a\u007fb.md"]) {
|
||||
assert.equal(isSafeFilename(bad), false, `should reject: ${JSON.stringify(bad)}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects path traversal", () => {
|
||||
assert.equal(isSafeFilename("../secrets.md"), false);
|
||||
assert.equal(isSafeFilename("a/../../b.md"), false);
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects empty and non-string input", () => {
|
||||
assert.equal(isSafeFilename(""), false);
|
||||
assert.equal(isSafeFilename(null), false);
|
||||
assert.equal(isSafeFilename(undefined), false);
|
||||
assert.equal(isSafeFilename(42), false);
|
||||
});
|
||||
"use strict";
|
||||
const test = require("node:test");
|
||||
const assert = require("node:assert/strict");
|
||||
const { isSafeFilename } = require("../main.js").__test__;
|
||||
|
||||
test("isSafeFilename accepts every filename currently in the vault", () => {
|
||||
const real = [
|
||||
"Agentic Engineering, explained by a 10x developer.md",
|
||||
"Webinar Plan - From Chat Box to Your Own OS.md",
|
||||
"Webinar script.md",
|
||||
"You're reading way too much code.md",
|
||||
"ИИ глупый!.md",
|
||||
"Скиллы на базе git — новая память AI-агентов.md",
|
||||
"sebastian interview - conclusions and insights.md",
|
||||
"In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md",
|
||||
];
|
||||
for (const name of real) {
|
||||
assert.equal(isSafeFilename(name), true, `should accept: ${name}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects shell metacharacters", () => {
|
||||
for (const bad of ['a".md', "a`b.md", "a$b.md", "a&b.md", "a|b.md", "a;b.md",
|
||||
"a<b.md", "a>b.md", "a%b.md", "a\nb.md", "a\rb.md"]) {
|
||||
assert.equal(isSafeFilename(bad), false, `should reject: ${JSON.stringify(bad)}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects the cmd.exe escape character and control characters", () => {
|
||||
// `^` escapes the next character in cmd.exe, so it can defuse the closing
|
||||
// quote. NUL additionally makes spawn() throw synchronously.
|
||||
for (const bad of ["a^b.md", "a\u0000b.md", "a\u001bb.md", "a\u007fb.md"]) {
|
||||
assert.equal(isSafeFilename(bad), false, `should reject: ${JSON.stringify(bad)}`);
|
||||
}
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects path traversal", () => {
|
||||
assert.equal(isSafeFilename("../secrets.md"), false);
|
||||
assert.equal(isSafeFilename("a/../../b.md"), false);
|
||||
});
|
||||
|
||||
test("isSafeFilename rejects empty and non-string input", () => {
|
||||
assert.equal(isSafeFilename(""), false);
|
||||
assert.equal(isSafeFilename(null), false);
|
||||
assert.equal(isSafeFilename(undefined), false);
|
||||
assert.equal(isSafeFilename(42), false);
|
||||
});
|
||||
|
||||
496
CLAUDE.md
496
CLAUDE.md
@@ -1,248 +1,248 @@
|
||||
# LLM Wiki Schema (Operational Contract)
|
||||
|
||||
You are the dedicated maintainer of this vault as a persistent, compounding wiki.
|
||||
|
||||
## Mission
|
||||
|
||||
Maintain a high-signal personal knowledge base where:
|
||||
|
||||
- `raw/` contains immutable source materials.
|
||||
- `wiki/` contains LLM-authored, continuously maintained markdown pages.
|
||||
- `index.md` is the content catalog.
|
||||
- `log.md` is an append-only chronological operation log.
|
||||
|
||||
The user curates sources and asks questions. You perform all wiki maintenance.
|
||||
|
||||
## Non-Negotiable Rules
|
||||
|
||||
1. Never modify files inside `raw/`.
|
||||
2. Always update `index.md` and `log.md` after any ingest/query/lint operation that changes the wiki.
|
||||
3. Prefer editing existing pages over creating duplicates.
|
||||
4. Use Obsidian-style wiki links (`[[page-name]]`) for internal references.
|
||||
5. Record contradictions and superseded claims explicitly (do not silently overwrite history).
|
||||
6. Keep claims attributable: include source links to `wiki/sources/*` pages.
|
||||
7. Do not leave orphan pages intentionally; add at least one inbound and one outbound link when possible.
|
||||
8. Keep writing concise, structured, and diff-friendly.
|
||||
9. Every wiki page carries exactly one page-type hashtag (see Tagging Rules) matching its folder.
|
||||
|
||||
## Folder Convention
|
||||
|
||||
```text
|
||||
raw/
|
||||
sources/ # immutable source markdown/text/pdf exports
|
||||
assets/ # immutable local images/files referenced by raw sources
|
||||
|
||||
wiki/
|
||||
overview.md # top-level synthesis and navigation
|
||||
script-coverage.md # machine-maintained: concept coverage vs the webinar script
|
||||
sources/ # one summary page per ingested raw source
|
||||
entities/ # people, orgs, projects, places, tools
|
||||
concepts/ # themes, ideas, methods, frameworks
|
||||
timelines/ # optional chronological reconstructions
|
||||
comparisons/ # side-by-side analyses
|
||||
queries/ # durable outputs created from Q&A sessions
|
||||
lint-reports/ # periodic health-check reports
|
||||
```
|
||||
|
||||
## File Naming Rules
|
||||
|
||||
- Use kebab-case for file names.
|
||||
- Prefix source summary pages with date: `YYYY-MM-DD-title.md`.
|
||||
- Prefer stable canonical pages:
|
||||
- `wiki/entities/<name>.md`
|
||||
- `wiki/concepts/<concept>.md`
|
||||
- If a page name collides, merge instead of creating suffixes unless truly distinct.
|
||||
|
||||
## Tagging Rules
|
||||
|
||||
Every page in `wiki/` starts with its page-type hashtag on its own line, directly after the `# <title>` heading (Obsidian inline tag format):
|
||||
|
||||
```text
|
||||
# <Title>
|
||||
|
||||
#<type-tag>
|
||||
|
||||
## <first section>
|
||||
```
|
||||
|
||||
Folder → required tag:
|
||||
|
||||
| Folder / file | Tag |
|
||||
| ---------------------- | -------------- |
|
||||
| `wiki/overview.md` | `#overview` |
|
||||
| `wiki/script-coverage.md` | `#coverage` |
|
||||
| `wiki/sources/*` | `#source` |
|
||||
| `wiki/entities/*` | `#entity` |
|
||||
| `wiki/concepts/*` | `#concept` |
|
||||
| `wiki/timelines/*` | `#timeline` |
|
||||
| `wiki/comparisons/*` | `#comparison` |
|
||||
| `wiki/queries/*` | `#query` |
|
||||
| `wiki/lint-reports/*` | `#lint-report` |
|
||||
|
||||
- Exactly one page-type tag per page; it must match the page's folder.
|
||||
- Additional topical tags are allowed on the same line after the type tag (e.g. `#concept #ai-tooling`), but the type tag comes first.
|
||||
- When creating any new page, add the tag immediately; when moving a page between folders, update the tag in the same operation.
|
||||
|
||||
## Required Page Templates
|
||||
|
||||
### 1) Source Summary (`wiki/sources/*.md`)
|
||||
|
||||
Must include sections:
|
||||
|
||||
- `# <title>`
|
||||
- `#source` tag line (per Tagging Rules)
|
||||
- `## Source Metadata` (date, raw path, source type, ingestion date)
|
||||
- `## Core Claims`
|
||||
- `## Key Evidence / Details`
|
||||
- `## Connections` (links to entities/concepts/comparisons)
|
||||
- `## Open Questions`
|
||||
- `## Change Impact on Wiki` (what pages were updated and why)
|
||||
|
||||
### 2) Entity / Concept Page
|
||||
|
||||
Must include:
|
||||
|
||||
- `# <name>`
|
||||
- `#entity` or `#concept` tag line (per Tagging Rules)
|
||||
- `## Summary`
|
||||
- `## Current Understanding`
|
||||
- `## Evidence` (bullets with links to `wiki/sources/*`)
|
||||
- `## Related Pages`
|
||||
- `## Contradictions / Uncertainty`
|
||||
- `## Next Questions`
|
||||
|
||||
### 3) Query Output (`wiki/queries/*.md`)
|
||||
|
||||
Must include:
|
||||
|
||||
- `#query` tag line (per Tagging Rules)
|
||||
- Question asked
|
||||
- Answer
|
||||
- Evidence trail (links)
|
||||
- Follow-up questions
|
||||
- Whether this output changed existing pages
|
||||
|
||||
### 4) Coverage File (`wiki/script-coverage.md`)
|
||||
|
||||
Machine-read by the dashboard plugin, which parses the table positionally. The
|
||||
shape below is required exactly — a deviation renders as parse errors, not as a
|
||||
best-effort read.
|
||||
|
||||
- `# Script coverage`
|
||||
- `#coverage` tag line
|
||||
- `## Metadata`, containing these two lines verbatim in this form:
|
||||
- `- **Script:** ` followed by the raw script path in backticks
|
||||
- `- **Last synced:** ` followed by a `YYYY-MM-DD` date
|
||||
- `## Coverage`, containing one markdown table with exactly these four columns in
|
||||
this order: `Concept`, `Status`, `Station`, `Pinned`
|
||||
- **Concept** — an Obsidian wikilink to a page in `wiki/concepts/`
|
||||
- **Status** — exactly one of `covered`, `partial`, `absent`, lowercase
|
||||
- **Station** — one of the seven station names spelled exactly as listed in
|
||||
Workflow D, a comma-separated list of them, the lowercase word `all`, or an
|
||||
em dash `—` when the status is `absent`
|
||||
- **Pinned** — the lowercase word `yes`, or empty
|
||||
- `## Notes` and `## Related Pages` are free prose and are not parsed.
|
||||
|
||||
The parser reads every markdown table in the file, so do not add a second table.
|
||||
|
||||
## Standard Workflows
|
||||
|
||||
### Workflow A: Ingest One Source
|
||||
|
||||
When user says "ingest <source>":
|
||||
|
||||
1. Read the raw source from `raw/sources/` (and `raw/assets/` references if needed).
|
||||
2. Extract key claims, facts, entities, concepts, uncertainty.
|
||||
3. Create/update one source summary in `wiki/sources/`.
|
||||
4. Update relevant `wiki/entities/*` and `wiki/concepts/*` pages.
|
||||
5. Update `wiki/overview.md` synthesis if this source materially changes understanding.
|
||||
6. Update `index.md`.
|
||||
7. Append ingest entry to `log.md`.
|
||||
8. Report what changed, what is uncertain, and suggested next source/questions.
|
||||
9. If this ingest created or modified any page in `wiki/concepts/`, run Workflow D
|
||||
(Sync Script Coverage) before reporting.
|
||||
|
||||
### Workflow B: Answer Query
|
||||
|
||||
1. Read `index.md` first.
|
||||
2. Select relevant pages and synthesize answer with page citations.
|
||||
3. If answer has durable value, save to `wiki/queries/YYYY-MM-DD-<slug>.md`.
|
||||
4. If answer reveals new synthesis, update affected concept/entity pages.
|
||||
5. Update `index.md` and append query entry in `log.md` when files changed.
|
||||
|
||||
### Workflow C: Lint Wiki
|
||||
|
||||
Run periodic health checks for:
|
||||
|
||||
- contradiction detection across pages
|
||||
- stale claims superseded by newer sources
|
||||
- orphan pages / weak linking
|
||||
- high-mention concepts lacking dedicated pages
|
||||
- missing evidence links
|
||||
- missing or folder-mismatched page-type tags (per Tagging Rules)
|
||||
|
||||
Write report to `wiki/lint-reports/YYYY-MM-DD-lint.md`, then update `index.md` and `log.md`.
|
||||
|
||||
### Workflow D: Sync Script Coverage
|
||||
|
||||
Maintains `wiki/script-coverage.md` — one row per page in `wiki/concepts/`, judged
|
||||
against the script named in that file's `**Script:**` metadata field.
|
||||
|
||||
1. Read `wiki/script-coverage.md` and note every row where `Pinned` is `yes`.
|
||||
2. Read the script and every page in `wiki/concepts/`.
|
||||
3. For each concept, decide `Status` and `Station`:
|
||||
- `covered` — the script delivers the idea, whether or not it uses the page's name.
|
||||
- `partial` — the script gestures at it but never lands it.
|
||||
- `absent` — the script never reaches it.
|
||||
- `Station` is one of the seven — `Chat box`, `ReAct`, `Tools`, `Memory`,
|
||||
`Skills`, `Process`, `OS` — spelled exactly as written here, or a
|
||||
comma-separated list of them, or the lowercase word `all`, or `—` when absent.
|
||||
4. **Never modify a row whose `Pinned` is `yes`** — not its status, not its station.
|
||||
A pinned row is the user's judgment and outranks yours.
|
||||
5. Add rows for concept pages with no row. Remove rows whose concept page no longer exists.
|
||||
A pinned row whose concept page no longer exists is still removed — step 4
|
||||
protects the user's judgement about a live concept, not a dangling row.
|
||||
6. Update `**Last synced:**` to today.
|
||||
7. Update `index.md` and append a `sync` entry to `log.md`.
|
||||
|
||||
Run this workflow:
|
||||
|
||||
- at the end of any ingest that creates or modifies a page in `wiki/concepts/`
|
||||
- whenever the script file itself changes
|
||||
- on the explicit `sync script coverage` intent
|
||||
|
||||
The coverage baseline is always the raw script. Ingesting the script into
|
||||
`wiki/sources/` does not change the baseline.
|
||||
|
||||
## Citation & Evidence Policy
|
||||
|
||||
- Prefer citing wiki source summaries (`wiki/sources/*.md`) rather than raw files in normal answers.
|
||||
- If citing raw material directly, also reflect it into a source summary page.
|
||||
- Mark uncertain or contested claims with `Status: tentative` in relevant section.
|
||||
|
||||
## Update Policy
|
||||
|
||||
- Never perform silent large rewrites.
|
||||
- Preserve meaningful prior interpretations; move outdated material under a "Superseded" note when needed.
|
||||
- Keep sections ordered consistently for predictable diffs.
|
||||
|
||||
## Operational Commands (Natural Language)
|
||||
|
||||
Supported intents:
|
||||
|
||||
- "ingest path-or-title"
|
||||
- "query: question"
|
||||
- "lint wiki"
|
||||
- "show recent changes"
|
||||
- "suggest next sources"
|
||||
- "sync script coverage"
|
||||
|
||||
Always execute intents according to workflows above.
|
||||
|
||||
## Session Start Checklist
|
||||
|
||||
At start of every session:
|
||||
|
||||
1. Read `index.md` and the latest section of `log.md`.
|
||||
2. Identify last completed operation and current open questions.
|
||||
3. Continue from prior state without resetting conventions.
|
||||
# LLM Wiki Schema (Operational Contract)
|
||||
|
||||
You are the dedicated maintainer of this vault as a persistent, compounding wiki.
|
||||
|
||||
## Mission
|
||||
|
||||
Maintain a high-signal personal knowledge base where:
|
||||
|
||||
- `raw/` contains immutable source materials.
|
||||
- `wiki/` contains LLM-authored, continuously maintained markdown pages.
|
||||
- `index.md` is the content catalog.
|
||||
- `log.md` is an append-only chronological operation log.
|
||||
|
||||
The user curates sources and asks questions. You perform all wiki maintenance.
|
||||
|
||||
## Non-Negotiable Rules
|
||||
|
||||
1. Never modify files inside `raw/`.
|
||||
2. Always update `index.md` and `log.md` after any ingest/query/lint operation that changes the wiki.
|
||||
3. Prefer editing existing pages over creating duplicates.
|
||||
4. Use Obsidian-style wiki links (`[[page-name]]`) for internal references.
|
||||
5. Record contradictions and superseded claims explicitly (do not silently overwrite history).
|
||||
6. Keep claims attributable: include source links to `wiki/sources/*` pages.
|
||||
7. Do not leave orphan pages intentionally; add at least one inbound and one outbound link when possible.
|
||||
8. Keep writing concise, structured, and diff-friendly.
|
||||
9. Every wiki page carries exactly one page-type hashtag (see Tagging Rules) matching its folder.
|
||||
|
||||
## Folder Convention
|
||||
|
||||
```text
|
||||
raw/
|
||||
sources/ # immutable source markdown/text/pdf exports
|
||||
assets/ # immutable local images/files referenced by raw sources
|
||||
|
||||
wiki/
|
||||
overview.md # top-level synthesis and navigation
|
||||
script-coverage.md # machine-maintained: concept coverage vs the webinar script
|
||||
sources/ # one summary page per ingested raw source
|
||||
entities/ # people, orgs, projects, places, tools
|
||||
concepts/ # themes, ideas, methods, frameworks
|
||||
timelines/ # optional chronological reconstructions
|
||||
comparisons/ # side-by-side analyses
|
||||
queries/ # durable outputs created from Q&A sessions
|
||||
lint-reports/ # periodic health-check reports
|
||||
```
|
||||
|
||||
## File Naming Rules
|
||||
|
||||
- Use kebab-case for file names.
|
||||
- Prefix source summary pages with date: `YYYY-MM-DD-title.md`.
|
||||
- Prefer stable canonical pages:
|
||||
- `wiki/entities/<name>.md`
|
||||
- `wiki/concepts/<concept>.md`
|
||||
- If a page name collides, merge instead of creating suffixes unless truly distinct.
|
||||
|
||||
## Tagging Rules
|
||||
|
||||
Every page in `wiki/` starts with its page-type hashtag on its own line, directly after the `# <title>` heading (Obsidian inline tag format):
|
||||
|
||||
```text
|
||||
# <Title>
|
||||
|
||||
#<type-tag>
|
||||
|
||||
## <first section>
|
||||
```
|
||||
|
||||
Folder → required tag:
|
||||
|
||||
| Folder / file | Tag |
|
||||
| ---------------------- | -------------- |
|
||||
| `wiki/overview.md` | `#overview` |
|
||||
| `wiki/script-coverage.md` | `#coverage` |
|
||||
| `wiki/sources/*` | `#source` |
|
||||
| `wiki/entities/*` | `#entity` |
|
||||
| `wiki/concepts/*` | `#concept` |
|
||||
| `wiki/timelines/*` | `#timeline` |
|
||||
| `wiki/comparisons/*` | `#comparison` |
|
||||
| `wiki/queries/*` | `#query` |
|
||||
| `wiki/lint-reports/*` | `#lint-report` |
|
||||
|
||||
- Exactly one page-type tag per page; it must match the page's folder.
|
||||
- Additional topical tags are allowed on the same line after the type tag (e.g. `#concept #ai-tooling`), but the type tag comes first.
|
||||
- When creating any new page, add the tag immediately; when moving a page between folders, update the tag in the same operation.
|
||||
|
||||
## Required Page Templates
|
||||
|
||||
### 1) Source Summary (`wiki/sources/*.md`)
|
||||
|
||||
Must include sections:
|
||||
|
||||
- `# <title>`
|
||||
- `#source` tag line (per Tagging Rules)
|
||||
- `## Source Metadata` (date, raw path, source type, ingestion date)
|
||||
- `## Core Claims`
|
||||
- `## Key Evidence / Details`
|
||||
- `## Connections` (links to entities/concepts/comparisons)
|
||||
- `## Open Questions`
|
||||
- `## Change Impact on Wiki` (what pages were updated and why)
|
||||
|
||||
### 2) Entity / Concept Page
|
||||
|
||||
Must include:
|
||||
|
||||
- `# <name>`
|
||||
- `#entity` or `#concept` tag line (per Tagging Rules)
|
||||
- `## Summary`
|
||||
- `## Current Understanding`
|
||||
- `## Evidence` (bullets with links to `wiki/sources/*`)
|
||||
- `## Related Pages`
|
||||
- `## Contradictions / Uncertainty`
|
||||
- `## Next Questions`
|
||||
|
||||
### 3) Query Output (`wiki/queries/*.md`)
|
||||
|
||||
Must include:
|
||||
|
||||
- `#query` tag line (per Tagging Rules)
|
||||
- Question asked
|
||||
- Answer
|
||||
- Evidence trail (links)
|
||||
- Follow-up questions
|
||||
- Whether this output changed existing pages
|
||||
|
||||
### 4) Coverage File (`wiki/script-coverage.md`)
|
||||
|
||||
Machine-read by the dashboard plugin, which parses the table positionally. The
|
||||
shape below is required exactly — a deviation renders as parse errors, not as a
|
||||
best-effort read.
|
||||
|
||||
- `# Script coverage`
|
||||
- `#coverage` tag line
|
||||
- `## Metadata`, containing these two lines verbatim in this form:
|
||||
- `- **Script:** ` followed by the raw script path in backticks
|
||||
- `- **Last synced:** ` followed by a `YYYY-MM-DD` date
|
||||
- `## Coverage`, containing one markdown table with exactly these four columns in
|
||||
this order: `Concept`, `Status`, `Station`, `Pinned`
|
||||
- **Concept** — an Obsidian wikilink to a page in `wiki/concepts/`
|
||||
- **Status** — exactly one of `covered`, `partial`, `absent`, lowercase
|
||||
- **Station** — one of the seven station names spelled exactly as listed in
|
||||
Workflow D, a comma-separated list of them, the lowercase word `all`, or an
|
||||
em dash `—` when the status is `absent`
|
||||
- **Pinned** — the lowercase word `yes`, or empty
|
||||
- `## Notes` and `## Related Pages` are free prose and are not parsed.
|
||||
|
||||
The parser reads every markdown table in the file, so do not add a second table.
|
||||
|
||||
## Standard Workflows
|
||||
|
||||
### Workflow A: Ingest One Source
|
||||
|
||||
When user says "ingest <source>":
|
||||
|
||||
1. Read the raw source from `raw/sources/` (and `raw/assets/` references if needed).
|
||||
2. Extract key claims, facts, entities, concepts, uncertainty.
|
||||
3. Create/update one source summary in `wiki/sources/`.
|
||||
4. Update relevant `wiki/entities/*` and `wiki/concepts/*` pages.
|
||||
5. Update `wiki/overview.md` synthesis if this source materially changes understanding.
|
||||
6. Update `index.md`.
|
||||
7. Append ingest entry to `log.md`.
|
||||
8. Report what changed, what is uncertain, and suggested next source/questions.
|
||||
9. If this ingest created or modified any page in `wiki/concepts/`, run Workflow D
|
||||
(Sync Script Coverage) before reporting.
|
||||
|
||||
### Workflow B: Answer Query
|
||||
|
||||
1. Read `index.md` first.
|
||||
2. Select relevant pages and synthesize answer with page citations.
|
||||
3. If answer has durable value, save to `wiki/queries/YYYY-MM-DD-<slug>.md`.
|
||||
4. If answer reveals new synthesis, update affected concept/entity pages.
|
||||
5. Update `index.md` and append query entry in `log.md` when files changed.
|
||||
|
||||
### Workflow C: Lint Wiki
|
||||
|
||||
Run periodic health checks for:
|
||||
|
||||
- contradiction detection across pages
|
||||
- stale claims superseded by newer sources
|
||||
- orphan pages / weak linking
|
||||
- high-mention concepts lacking dedicated pages
|
||||
- missing evidence links
|
||||
- missing or folder-mismatched page-type tags (per Tagging Rules)
|
||||
|
||||
Write report to `wiki/lint-reports/YYYY-MM-DD-lint.md`, then update `index.md` and `log.md`.
|
||||
|
||||
### Workflow D: Sync Script Coverage
|
||||
|
||||
Maintains `wiki/script-coverage.md` — one row per page in `wiki/concepts/`, judged
|
||||
against the script named in that file's `**Script:**` metadata field.
|
||||
|
||||
1. Read `wiki/script-coverage.md` and note every row where `Pinned` is `yes`.
|
||||
2. Read the script and every page in `wiki/concepts/`.
|
||||
3. For each concept, decide `Status` and `Station`:
|
||||
- `covered` — the script delivers the idea, whether or not it uses the page's name.
|
||||
- `partial` — the script gestures at it but never lands it.
|
||||
- `absent` — the script never reaches it.
|
||||
- `Station` is one of the seven — `Chat box`, `ReAct`, `Tools`, `Memory`,
|
||||
`Skills`, `Process`, `OS` — spelled exactly as written here, or a
|
||||
comma-separated list of them, or the lowercase word `all`, or `—` when absent.
|
||||
4. **Never modify a row whose `Pinned` is `yes`** — not its status, not its station.
|
||||
A pinned row is the user's judgment and outranks yours.
|
||||
5. Add rows for concept pages with no row. Remove rows whose concept page no longer exists.
|
||||
A pinned row whose concept page no longer exists is still removed — step 4
|
||||
protects the user's judgement about a live concept, not a dangling row.
|
||||
6. Update `**Last synced:**` to today.
|
||||
7. Update `index.md` and append a `sync` entry to `log.md`.
|
||||
|
||||
Run this workflow:
|
||||
|
||||
- at the end of any ingest that creates or modifies a page in `wiki/concepts/`
|
||||
- whenever the script file itself changes
|
||||
- on the explicit `sync script coverage` intent
|
||||
|
||||
The coverage baseline is always the raw script. Ingesting the script into
|
||||
`wiki/sources/` does not change the baseline.
|
||||
|
||||
## Citation & Evidence Policy
|
||||
|
||||
- Prefer citing wiki source summaries (`wiki/sources/*.md`) rather than raw files in normal answers.
|
||||
- If citing raw material directly, also reflect it into a source summary page.
|
||||
- Mark uncertain or contested claims with `Status: tentative` in relevant section.
|
||||
|
||||
## Update Policy
|
||||
|
||||
- Never perform silent large rewrites.
|
||||
- Preserve meaningful prior interpretations; move outdated material under a "Superseded" note when needed.
|
||||
- Keep sections ordered consistently for predictable diffs.
|
||||
|
||||
## Operational Commands (Natural Language)
|
||||
|
||||
Supported intents:
|
||||
|
||||
- "ingest path-or-title"
|
||||
- "query: question"
|
||||
- "lint wiki"
|
||||
- "show recent changes"
|
||||
- "suggest next sources"
|
||||
- "sync script coverage"
|
||||
|
||||
Always execute intents according to workflows above.
|
||||
|
||||
## Session Start Checklist
|
||||
|
||||
At start of every session:
|
||||
|
||||
1. Read `index.md` and the latest section of `log.md`.
|
||||
2. Identify last completed operation and current open questions.
|
||||
3. Continue from prior state without resetting conventions.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,256 +1,256 @@
|
||||
# Webinar vault dashboard — design
|
||||
|
||||
Date: 2026-07-28
|
||||
Status: approved, ready for implementation planning
|
||||
|
||||
## Context
|
||||
|
||||
The vault is an LLM-maintained wiki governed by `CLAUDE.md`. It currently holds 12 raw
|
||||
sources, 9 ingested source summaries, 19 concept pages, and one webinar script
|
||||
(`raw/sources/Webinar script.md`) that the concepts are supposed to feed.
|
||||
|
||||
Two problems motivated this work:
|
||||
|
||||
1. **The manual catalog drifts.** `index.md` lists `Ideas for webinar.md` and
|
||||
`my theses.md` under `raw/sources/`, but both live in `raw/notes/`. It does not
|
||||
mention `Agentic Engineering, explained by a 10x developer.md` at all, which sits
|
||||
un-ingested in `raw/sources/`. Nothing detects this.
|
||||
2. **No view of script coverage.** There is no way to see which concept pages the
|
||||
webinar script actually delivers. A manual read shows the script is entirely
|
||||
machine-side: all human-side and strategy-side concepts are absent.
|
||||
|
||||
## Goals
|
||||
|
||||
- Show processed and unprocessed sources, with a one-click ingest on the unprocessed.
|
||||
- Show every concept and whether the webinar script mentions it, plus which script
|
||||
station it lands in.
|
||||
- Keep coverage status in a separate markdown file, kept synchronized by a rule in
|
||||
`CLAUDE.md`.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Replacing `index.md` or `log.md`. Both stay exactly as they are.
|
||||
- A general-purpose Obsidian dashboard framework. This is one vault-specific plugin.
|
||||
- Publishing the plugin to the community plugin registry.
|
||||
|
||||
## Decisions taken
|
||||
|
||||
| Decision | Choice | Rationale |
|
||||
|---|---|---|
|
||||
| Buttons | Own plugin, not Meta Bind | Needs are narrow and vault-specific; Meta Bind's expensive half (inline CM6 widgets, two-way frontmatter binding) is unused here |
|
||||
| Coverage status source | Claude judges; user can pin | Sync sets status automatically, but a row marked `Pinned: yes` is never overwritten |
|
||||
| Ingest mechanism | Headless `claude -p` via `child_process` | One click, fully automatic. Chosen over a queue file with the unsupervised-write trade-off understood |
|
||||
| Granularity | Status + script station | Turns the table into a pacing map, not just a checklist |
|
||||
| Layout | Two-pane (Option B) | Sources and coverage both first-class; coverage grouped by station recovers most of the station-board view |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
.obsidian/plugins/webinar-dash/
|
||||
manifest.json
|
||||
main.js # plain CommonJS, no build step
|
||||
styles.css # tesanti tokens scoped to .webinar-dash
|
||||
|
||||
dashboard.md # vault root, beside index.md
|
||||
wiki/script-coverage.md # the coverage table
|
||||
```
|
||||
|
||||
`dashboard.md` holds only a config block; the plugin renders everything:
|
||||
|
||||
````markdown
|
||||
# Webinar dashboard
|
||||
|
||||
```webinar-dash
|
||||
script: raw/sources/Webinar script.md
|
||||
coverage: wiki/script-coverage.md
|
||||
```
|
||||
````
|
||||
|
||||
Config keys are optional and fall back to those two defaults.
|
||||
|
||||
### Where truth lives
|
||||
|
||||
| Data | Source of truth | Mechanism |
|
||||
|---|---|---|
|
||||
| Which sources are processed | Filesystem, read live | Diff `raw/sources/*.md` against the `**Raw path:**` value in every `wiki/sources/*.md` |
|
||||
| Concept coverage status | `wiki/script-coverage.md` | Written by Claude on sync, read by the plugin |
|
||||
|
||||
Mechanical facts come from the filesystem, judgment comes from the markdown file.
|
||||
This makes the `index.md` class of drift structurally impossible on the sources half:
|
||||
the dashboard cannot disagree with the filesystem because it derives from it.
|
||||
|
||||
**The plugin never writes to the vault.** It reads files and spawns one subprocess.
|
||||
Nothing else. It also never reads `index.md` — the catalog is a human-facing artifact,
|
||||
and treating it as input would reintroduce exactly the drift this design removes.
|
||||
|
||||
### Source pipeline derivation
|
||||
|
||||
1. List `raw/sources/*.md`.
|
||||
2. For each `wiki/sources/*.md`, extract the backticked path from the line matching
|
||||
`**Raw path:** \`<path>\``. Verified consistent across all 9 existing source pages.
|
||||
3. A raw file claimed by some source page is **processed**; unclaimed is **unprocessed**.
|
||||
4. A source page whose raw path no longer exists is reported as **orphaned**.
|
||||
|
||||
`raw/notes/` is out of scope — those are notes, not sources.
|
||||
|
||||
## Coverage file format
|
||||
|
||||
```markdown
|
||||
# Script coverage
|
||||
|
||||
#coverage
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Script:** `raw/sources/Webinar script.md`
|
||||
- **Last synced:** 2026-07-28
|
||||
- **Stations:** Chat box · ReAct · Tools · Memory · Skills · Process · OS
|
||||
|
||||
## Coverage
|
||||
|
||||
| Concept | Status | Station | Pinned |
|
||||
|---|---|---|---|
|
||||
| [[harness]] | covered | Tools | |
|
||||
| [[agentic-loops]] | partial | Process | |
|
||||
| [[levels-of-ai-usage]] | partial | all | |
|
||||
| [[connections-as-moat]] | absent | — | yes |
|
||||
```
|
||||
|
||||
Field rules:
|
||||
|
||||
- **Concept** — an Obsidian wikilink to a page in `wiki/concepts/`. The plugin extracts
|
||||
the page name from inside the brackets.
|
||||
- **Status** — exactly one of `covered`, `partial`, `absent`. Any other value renders as
|
||||
`invalid` rather than being silently coerced.
|
||||
- **Station** — one of the seven station names, a comma-separated list of them, `all`,
|
||||
or `—` for none.
|
||||
- **Pinned** — `yes`, or blank. Blank is the default.
|
||||
|
||||
The seven stations are the `#` headings of the script that represent technology levels:
|
||||
Chat box, ReAct, Tools, Memory, Skills, Process, OS. The script's `Intro`,
|
||||
`Mail from boss`, and `Notes` headings are setup and are not stations.
|
||||
|
||||
v1 does not write this file from the plugin. Pinning is a hand-edit of one cell — a pin
|
||||
toggle button would make the plugin a writer and risk clobbering concurrent user edits,
|
||||
which is not worth it for a one-word change.
|
||||
|
||||
## Rendering — two-pane layout
|
||||
|
||||
Left pane (38%):
|
||||
- **Queue** — unprocessed sources, each row showing filename, byte size, and an
|
||||
**Ingest** button. Files missing from `index.md` need no special flag: they appear
|
||||
here purely because no source page claims them, which is how
|
||||
`Agentic Engineering, explained by a 10x developer.md` surfaces despite being absent
|
||||
from the catalog.
|
||||
- **Ingested** — processed sources as compact rows: date from the source page filename
|
||||
prefix, plus title.
|
||||
|
||||
Right pane (62%):
|
||||
- Coverage meter — a stacked bar of covered / partial / absent with a 2px gap between
|
||||
segments, plus a counted key.
|
||||
- Coverage table grouped by station, with `No station` last.
|
||||
|
||||
Collapses to a single column below 820px so a narrow Obsidian pane stays usable.
|
||||
|
||||
Styling follows the tesanti design system: black / white / red only, Space Grotesk
|
||||
display, Inter body, JetBrains Mono for eyebrows and data, radii at most 6px, 1px
|
||||
hairlines instead of shadows, Lucide stroke icons, no emoji. Status colors use the
|
||||
system's `--ok` / `--warn` / `--danger` tokens and always ship with a text label, never
|
||||
color alone. Dark mode is derived from the same ink ramp, with the red lifted to
|
||||
`#ff4a3d` so small text clears contrast on near-black.
|
||||
|
||||
## Ingest mechanism
|
||||
|
||||
```js
|
||||
const { spawn } = require("child_process");
|
||||
spawn("claude", ["-p", `ingest "${file}"`], { cwd: vaultPath, shell: true });
|
||||
```
|
||||
|
||||
`shell: true` is required on Windows to resolve `claude.cmd`, which places the filename
|
||||
inside a shell string. Before spawning, the filename is rejected if it contains any of:
|
||||
`"` `` ` `` `$` `&` `|` `;` `<` `>` `%` or a newline. Existing filenames include
|
||||
Cyrillic, spaces, and `!`, all of which pass. A rejected filename shows an error in its
|
||||
row and does not spawn.
|
||||
|
||||
Vault path comes from `app.vault.adapter.getBasePath()` on `FileSystemAdapter`.
|
||||
|
||||
Per-row states: `idle` → `running` with elapsed seconds → `done` or `failed · exit <n>`
|
||||
with captured stderr in an expandable block. On success the pipeline is re-derived and
|
||||
the row moves to the ingested list. A second click while running is ignored.
|
||||
|
||||
A global **Sync coverage** button spawns `claude -p "sync script coverage"`.
|
||||
|
||||
Preflight: if `claude` is not resolvable on PATH, all buttons render disabled with that
|
||||
reason stated.
|
||||
|
||||
### Accepted risk
|
||||
|
||||
Headless ingest writes source summaries, concept pages, `index.md`, and `log.md` without
|
||||
the user watching. This was chosen deliberately over a review checkpoint. Mitigations:
|
||||
one file per click rather than a batch, captured output retained per row, and visible
|
||||
per-row status. The writes land before the user reads them; this is understood and
|
||||
accepted.
|
||||
|
||||
## CLAUDE.md changes
|
||||
|
||||
1. **Folder convention** — add `wiki/script-coverage.md` to the tree with a note that it
|
||||
is machine-maintained.
|
||||
2. **Tagging rules** — add the row `wiki/script-coverage.md` → `#coverage`. No existing
|
||||
page type fits: it is generated tabular data, not prose analysis.
|
||||
3. **Workflow D: Sync Script Coverage** — re-read the script and every
|
||||
`wiki/concepts/*.md`; set `Status` and `Station` for each; never modify a row whose
|
||||
`Pinned` is `yes`; add rows for new concept pages; remove rows for deleted ones;
|
||||
update `Last synced`; then update `index.md` and append to `log.md`.
|
||||
4. **Sync triggers** — Workflow D runs at the end of any ingest that creates or modifies
|
||||
a concept page, whenever `Webinar script.md` changes, and on the explicit
|
||||
`sync script coverage` intent, which is added to Operational Commands.
|
||||
|
||||
The coverage baseline is always the raw script at `raw/sources/Webinar script.md`.
|
||||
Ingesting the script into `wiki/sources/` later does not change the baseline.
|
||||
|
||||
## Failure modes
|
||||
|
||||
| Condition | Behavior |
|
||||
|---|---|
|
||||
| Coverage file missing or table malformed | Sources pane renders normally; coverage pane shows a parse error with the offending line |
|
||||
| Concept page exists with no table row | Rendered as `unsynced`, so a stale sync is visible rather than silent |
|
||||
| Table row points at a nonexistent concept page | Rendered as `stale`, kept in place, not auto-removed |
|
||||
| Source page whose raw path is missing | Listed under `orphaned` in the left pane |
|
||||
| `child_process` unavailable (mobile) | Buttons render disabled with the reason |
|
||||
| `claude` not on PATH | Buttons render disabled with the reason |
|
||||
|
||||
## Initial coverage assessment
|
||||
|
||||
Read manually while designing; the first real sync will regenerate it. 19 concepts:
|
||||
5 covered, 4 partial, 10 absent.
|
||||
|
||||
- **covered** — harness (Tools), skills-as-memory (Skills), solve-first-then-skillify
|
||||
(Skills), personal-ai-operating-system (OS), evolution-of-agent-tooling (Tools)
|
||||
- **partial** — agentic-loops (Process), context-as-scarce-resource (Memory),
|
||||
levels-of-ai-usage (all), code-as-throwaway (OS)
|
||||
- **absent** — connections-as-moat, product-ownership, seniority-and-the-junior-squeeze,
|
||||
decoupling-identity-from-profession, network-from-a-standing-start,
|
||||
think-wider-not-bigger, make-more-cheap-code, enterprise-ai-reality,
|
||||
integration-dead-ends, leave-less-room-for-imagination
|
||||
|
||||
Eight of the ten absent concepts are human-side or strategy-side per `index.md`'s grouping.
|
||||
The other two — `integration-dead-ends` and `leave-less-room-for-imagination` — are
|
||||
machine-side, and are absent because the script demonstrates the happy path and so never
|
||||
reaches connector gating or spec ambiguity, the two ways the machine side fails in
|
||||
practice. The `ReAct` station carries no wiki concept at all.
|
||||
|
||||
## Out of scope for v1
|
||||
|
||||
- Pin toggle button (hand-edit instead).
|
||||
- Alternate station-board view toggle. The data file is layout-independent, so this is a
|
||||
render change if wanted later.
|
||||
- Coverage for entities, sources, or queries — concepts only.
|
||||
- Any view of `raw/notes/`.
|
||||
|
||||
## Note on spec location
|
||||
|
||||
This file introduces a `docs/` folder at the vault root, which is not part of the
|
||||
`CLAUDE.md` folder convention and will appear in Obsidian's file explorer. It can be
|
||||
moved or deleted without affecting the implementation.
|
||||
|
||||
The vault is not a git repository, so this spec is not committed.
|
||||
# Webinar vault dashboard — design
|
||||
|
||||
Date: 2026-07-28
|
||||
Status: approved, ready for implementation planning
|
||||
|
||||
## Context
|
||||
|
||||
The vault is an LLM-maintained wiki governed by `CLAUDE.md`. It currently holds 12 raw
|
||||
sources, 9 ingested source summaries, 19 concept pages, and one webinar script
|
||||
(`raw/sources/Webinar script.md`) that the concepts are supposed to feed.
|
||||
|
||||
Two problems motivated this work:
|
||||
|
||||
1. **The manual catalog drifts.** `index.md` lists `Ideas for webinar.md` and
|
||||
`my theses.md` under `raw/sources/`, but both live in `raw/notes/`. It does not
|
||||
mention `Agentic Engineering, explained by a 10x developer.md` at all, which sits
|
||||
un-ingested in `raw/sources/`. Nothing detects this.
|
||||
2. **No view of script coverage.** There is no way to see which concept pages the
|
||||
webinar script actually delivers. A manual read shows the script is entirely
|
||||
machine-side: all human-side and strategy-side concepts are absent.
|
||||
|
||||
## Goals
|
||||
|
||||
- Show processed and unprocessed sources, with a one-click ingest on the unprocessed.
|
||||
- Show every concept and whether the webinar script mentions it, plus which script
|
||||
station it lands in.
|
||||
- Keep coverage status in a separate markdown file, kept synchronized by a rule in
|
||||
`CLAUDE.md`.
|
||||
|
||||
## Non-goals
|
||||
|
||||
- Replacing `index.md` or `log.md`. Both stay exactly as they are.
|
||||
- A general-purpose Obsidian dashboard framework. This is one vault-specific plugin.
|
||||
- Publishing the plugin to the community plugin registry.
|
||||
|
||||
## Decisions taken
|
||||
|
||||
| Decision | Choice | Rationale |
|
||||
|---|---|---|
|
||||
| Buttons | Own plugin, not Meta Bind | Needs are narrow and vault-specific; Meta Bind's expensive half (inline CM6 widgets, two-way frontmatter binding) is unused here |
|
||||
| Coverage status source | Claude judges; user can pin | Sync sets status automatically, but a row marked `Pinned: yes` is never overwritten |
|
||||
| Ingest mechanism | Headless `claude -p` via `child_process` | One click, fully automatic. Chosen over a queue file with the unsupervised-write trade-off understood |
|
||||
| Granularity | Status + script station | Turns the table into a pacing map, not just a checklist |
|
||||
| Layout | Two-pane (Option B) | Sources and coverage both first-class; coverage grouped by station recovers most of the station-board view |
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
.obsidian/plugins/webinar-dash/
|
||||
manifest.json
|
||||
main.js # plain CommonJS, no build step
|
||||
styles.css # tesanti tokens scoped to .webinar-dash
|
||||
|
||||
dashboard.md # vault root, beside index.md
|
||||
wiki/script-coverage.md # the coverage table
|
||||
```
|
||||
|
||||
`dashboard.md` holds only a config block; the plugin renders everything:
|
||||
|
||||
````markdown
|
||||
# Webinar dashboard
|
||||
|
||||
```webinar-dash
|
||||
script: raw/sources/Webinar script.md
|
||||
coverage: wiki/script-coverage.md
|
||||
```
|
||||
````
|
||||
|
||||
Config keys are optional and fall back to those two defaults.
|
||||
|
||||
### Where truth lives
|
||||
|
||||
| Data | Source of truth | Mechanism |
|
||||
|---|---|---|
|
||||
| Which sources are processed | Filesystem, read live | Diff `raw/sources/*.md` against the `**Raw path:**` value in every `wiki/sources/*.md` |
|
||||
| Concept coverage status | `wiki/script-coverage.md` | Written by Claude on sync, read by the plugin |
|
||||
|
||||
Mechanical facts come from the filesystem, judgment comes from the markdown file.
|
||||
This makes the `index.md` class of drift structurally impossible on the sources half:
|
||||
the dashboard cannot disagree with the filesystem because it derives from it.
|
||||
|
||||
**The plugin never writes to the vault.** It reads files and spawns one subprocess.
|
||||
Nothing else. It also never reads `index.md` — the catalog is a human-facing artifact,
|
||||
and treating it as input would reintroduce exactly the drift this design removes.
|
||||
|
||||
### Source pipeline derivation
|
||||
|
||||
1. List `raw/sources/*.md`.
|
||||
2. For each `wiki/sources/*.md`, extract the backticked path from the line matching
|
||||
`**Raw path:** \`<path>\``. Verified consistent across all 9 existing source pages.
|
||||
3. A raw file claimed by some source page is **processed**; unclaimed is **unprocessed**.
|
||||
4. A source page whose raw path no longer exists is reported as **orphaned**.
|
||||
|
||||
`raw/notes/` is out of scope — those are notes, not sources.
|
||||
|
||||
## Coverage file format
|
||||
|
||||
```markdown
|
||||
# Script coverage
|
||||
|
||||
#coverage
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Script:** `raw/sources/Webinar script.md`
|
||||
- **Last synced:** 2026-07-28
|
||||
- **Stations:** Chat box · ReAct · Tools · Memory · Skills · Process · OS
|
||||
|
||||
## Coverage
|
||||
|
||||
| Concept | Status | Station | Pinned |
|
||||
|---|---|---|---|
|
||||
| [[harness]] | covered | Tools | |
|
||||
| [[agentic-loops]] | partial | Process | |
|
||||
| [[levels-of-ai-usage]] | partial | all | |
|
||||
| [[connections-as-moat]] | absent | — | yes |
|
||||
```
|
||||
|
||||
Field rules:
|
||||
|
||||
- **Concept** — an Obsidian wikilink to a page in `wiki/concepts/`. The plugin extracts
|
||||
the page name from inside the brackets.
|
||||
- **Status** — exactly one of `covered`, `partial`, `absent`. Any other value renders as
|
||||
`invalid` rather than being silently coerced.
|
||||
- **Station** — one of the seven station names, a comma-separated list of them, `all`,
|
||||
or `—` for none.
|
||||
- **Pinned** — `yes`, or blank. Blank is the default.
|
||||
|
||||
The seven stations are the `#` headings of the script that represent technology levels:
|
||||
Chat box, ReAct, Tools, Memory, Skills, Process, OS. The script's `Intro`,
|
||||
`Mail from boss`, and `Notes` headings are setup and are not stations.
|
||||
|
||||
v1 does not write this file from the plugin. Pinning is a hand-edit of one cell — a pin
|
||||
toggle button would make the plugin a writer and risk clobbering concurrent user edits,
|
||||
which is not worth it for a one-word change.
|
||||
|
||||
## Rendering — two-pane layout
|
||||
|
||||
Left pane (38%):
|
||||
- **Queue** — unprocessed sources, each row showing filename, byte size, and an
|
||||
**Ingest** button. Files missing from `index.md` need no special flag: they appear
|
||||
here purely because no source page claims them, which is how
|
||||
`Agentic Engineering, explained by a 10x developer.md` surfaces despite being absent
|
||||
from the catalog.
|
||||
- **Ingested** — processed sources as compact rows: date from the source page filename
|
||||
prefix, plus title.
|
||||
|
||||
Right pane (62%):
|
||||
- Coverage meter — a stacked bar of covered / partial / absent with a 2px gap between
|
||||
segments, plus a counted key.
|
||||
- Coverage table grouped by station, with `No station` last.
|
||||
|
||||
Collapses to a single column below 820px so a narrow Obsidian pane stays usable.
|
||||
|
||||
Styling follows the tesanti design system: black / white / red only, Space Grotesk
|
||||
display, Inter body, JetBrains Mono for eyebrows and data, radii at most 6px, 1px
|
||||
hairlines instead of shadows, Lucide stroke icons, no emoji. Status colors use the
|
||||
system's `--ok` / `--warn` / `--danger` tokens and always ship with a text label, never
|
||||
color alone. Dark mode is derived from the same ink ramp, with the red lifted to
|
||||
`#ff4a3d` so small text clears contrast on near-black.
|
||||
|
||||
## Ingest mechanism
|
||||
|
||||
```js
|
||||
const { spawn } = require("child_process");
|
||||
spawn("claude", ["-p", `ingest "${file}"`], { cwd: vaultPath, shell: true });
|
||||
```
|
||||
|
||||
`shell: true` is required on Windows to resolve `claude.cmd`, which places the filename
|
||||
inside a shell string. Before spawning, the filename is rejected if it contains any of:
|
||||
`"` `` ` `` `$` `&` `|` `;` `<` `>` `%` or a newline. Existing filenames include
|
||||
Cyrillic, spaces, and `!`, all of which pass. A rejected filename shows an error in its
|
||||
row and does not spawn.
|
||||
|
||||
Vault path comes from `app.vault.adapter.getBasePath()` on `FileSystemAdapter`.
|
||||
|
||||
Per-row states: `idle` → `running` with elapsed seconds → `done` or `failed · exit <n>`
|
||||
with captured stderr in an expandable block. On success the pipeline is re-derived and
|
||||
the row moves to the ingested list. A second click while running is ignored.
|
||||
|
||||
A global **Sync coverage** button spawns `claude -p "sync script coverage"`.
|
||||
|
||||
Preflight: if `claude` is not resolvable on PATH, all buttons render disabled with that
|
||||
reason stated.
|
||||
|
||||
### Accepted risk
|
||||
|
||||
Headless ingest writes source summaries, concept pages, `index.md`, and `log.md` without
|
||||
the user watching. This was chosen deliberately over a review checkpoint. Mitigations:
|
||||
one file per click rather than a batch, captured output retained per row, and visible
|
||||
per-row status. The writes land before the user reads them; this is understood and
|
||||
accepted.
|
||||
|
||||
## CLAUDE.md changes
|
||||
|
||||
1. **Folder convention** — add `wiki/script-coverage.md` to the tree with a note that it
|
||||
is machine-maintained.
|
||||
2. **Tagging rules** — add the row `wiki/script-coverage.md` → `#coverage`. No existing
|
||||
page type fits: it is generated tabular data, not prose analysis.
|
||||
3. **Workflow D: Sync Script Coverage** — re-read the script and every
|
||||
`wiki/concepts/*.md`; set `Status` and `Station` for each; never modify a row whose
|
||||
`Pinned` is `yes`; add rows for new concept pages; remove rows for deleted ones;
|
||||
update `Last synced`; then update `index.md` and append to `log.md`.
|
||||
4. **Sync triggers** — Workflow D runs at the end of any ingest that creates or modifies
|
||||
a concept page, whenever `Webinar script.md` changes, and on the explicit
|
||||
`sync script coverage` intent, which is added to Operational Commands.
|
||||
|
||||
The coverage baseline is always the raw script at `raw/sources/Webinar script.md`.
|
||||
Ingesting the script into `wiki/sources/` later does not change the baseline.
|
||||
|
||||
## Failure modes
|
||||
|
||||
| Condition | Behavior |
|
||||
|---|---|
|
||||
| Coverage file missing or table malformed | Sources pane renders normally; coverage pane shows a parse error with the offending line |
|
||||
| Concept page exists with no table row | Rendered as `unsynced`, so a stale sync is visible rather than silent |
|
||||
| Table row points at a nonexistent concept page | Rendered as `stale`, kept in place, not auto-removed |
|
||||
| Source page whose raw path is missing | Listed under `orphaned` in the left pane |
|
||||
| `child_process` unavailable (mobile) | Buttons render disabled with the reason |
|
||||
| `claude` not on PATH | Buttons render disabled with the reason |
|
||||
|
||||
## Initial coverage assessment
|
||||
|
||||
Read manually while designing; the first real sync will regenerate it. 19 concepts:
|
||||
5 covered, 4 partial, 10 absent.
|
||||
|
||||
- **covered** — harness (Tools), skills-as-memory (Skills), solve-first-then-skillify
|
||||
(Skills), personal-ai-operating-system (OS), evolution-of-agent-tooling (Tools)
|
||||
- **partial** — agentic-loops (Process), context-as-scarce-resource (Memory),
|
||||
levels-of-ai-usage (all), code-as-throwaway (OS)
|
||||
- **absent** — connections-as-moat, product-ownership, seniority-and-the-junior-squeeze,
|
||||
decoupling-identity-from-profession, network-from-a-standing-start,
|
||||
think-wider-not-bigger, make-more-cheap-code, enterprise-ai-reality,
|
||||
integration-dead-ends, leave-less-room-for-imagination
|
||||
|
||||
Eight of the ten absent concepts are human-side or strategy-side per `index.md`'s grouping.
|
||||
The other two — `integration-dead-ends` and `leave-less-room-for-imagination` — are
|
||||
machine-side, and are absent because the script demonstrates the happy path and so never
|
||||
reaches connector gating or spec ambiguity, the two ways the machine side fails in
|
||||
practice. The `ReAct` station carries no wiki concept at all.
|
||||
|
||||
## Out of scope for v1
|
||||
|
||||
- Pin toggle button (hand-edit instead).
|
||||
- Alternate station-board view toggle. The data file is layout-independent, so this is a
|
||||
render change if wanted later.
|
||||
- Coverage for entities, sources, or queries — concepts only.
|
||||
- Any view of `raw/notes/`.
|
||||
|
||||
## Note on spec location
|
||||
|
||||
This file introduces a `docs/` folder at the vault root, which is not part of the
|
||||
`CLAUDE.md` folder convention and will appear in Obsidian's file explorer. It can be
|
||||
moved or deleted without affecting the implementation.
|
||||
|
||||
The vault is not a git repository, so this spec is not committed.
|
||||
|
||||
178
index.md
178
index.md
@@ -1,89 +1,89 @@
|
||||
# Wiki Index
|
||||
|
||||
Content catalog for this vault. Updated after every ingest / query / lint operation that changes the wiki.
|
||||
|
||||
See [[overview]] for the top-level synthesis and navigation.
|
||||
|
||||
Every wiki page carries a page-type tag under its H1 (`#source`, `#entity`, `#concept`, `#timeline`, `#comparison`, `#query`, `#lint-report`, `#overview`) — see "Tagging Rules" in `CLAUDE.md`.
|
||||
|
||||
## Sources
|
||||
|
||||
- [[2026-07-14-everything-we-knew-about-software-has-changed]] — Theo Browne (AIE): model eras, think wider, code as throwaway _(raw: Everything we knew about software has changed.md)_
|
||||
- [[2026-07-14-gap-between-ai-users-irreversible]] — Allie Miller: personal AI OS, foundation docs, skills, proactive workflows _(raw: In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md)_
|
||||
- [[2026-07-14-sebastian-eugene-interview]] — Sebastian + Eugene: harness, team collapse, connections, enterprise reality _(raw: sebastian interview - conclusions and insights.md)_
|
||||
- [[2026-07-14-skills-based-on-git]] — Konstantin (Sber): git skills as agent memory, harness, agent loops _(raw: Скиллы на базе git — новая память AI-агентов.md)_
|
||||
- [[2026-07-14-nina-interview]] — Eugene + Nina (HR): transcript > summary, friction not resistance, skills as handoff _(raw: Nina interview.md)_
|
||||
- [[2026-07-14-yulia-interview]] — Eugene + Yulia (HR lead): levels of AI usage, candidate knowledge base, solve-first _(raw: Yulia interview.md)_
|
||||
- [[2026-07-21-larysa-interview]] — Eugene + Larysa (BA/PM): memory loss, integration dead-ends, less room for imagination _(raw: Larysa interview.md)_
|
||||
- [[2026-07-22-ai-is-stupid]] — YouTube short (author unknown): "stupid AI" = model minus context minus harness; Nobel-vs-employee analogy _(raw: ИИ глупый!.md)_
|
||||
- [[2026-07-24-youre-reading-way-too-much-code]] — Theo Browne (video): make more cheap code, four tiers of code, 100:1 slop-to-ship verification _(raw: You're reading way too much code.md)_
|
||||
|
||||
**Raw, not yet ingested:** `raw/sources/Agentic Engineering, explained by a 10x developer.md` · `raw/sources/Webinar Plan - From Chat Box to Your Own OS.md` · `raw/sources/Webinar script.md`
|
||||
|
||||
## Coverage
|
||||
|
||||
- [[script-coverage]] — every concept vs `raw/sources/Webinar script.md`; 5 covered, 4 partial, 10 absent
|
||||
|
||||
## Entities
|
||||
|
||||
### People
|
||||
- [[theo-browne]] — developer/educator (t3.gg); "think wider", "make more cheap code"
|
||||
- [[allie-miller]] — ex-Amazon AI leader; personal AI OS
|
||||
- [[sebastian]] — founder of Virtido; enterprise/connections lens
|
||||
- [[eugene]] — developer, harness-builder, webinar author; interviewer (likely vault owner, tentative)
|
||||
- [[konstantin]] — Sber/GigaChat R&D; skills-as-memory
|
||||
- [[nina]] — HR recruiter at Virtido; webinar-audience proxy, use-case supplier
|
||||
- [[yulia]] — HR/recruiting lead; webinar organizer (name/affiliation tentative)
|
||||
- [[larysa]] — technical BA/PM, ex-mobile dev; advanced user blocked by memory + integrations
|
||||
|
||||
### Tools / Orgs
|
||||
- [[claude-code]] — reference harness (all sources)
|
||||
- [[hermes]] — skills-first, self-curating harness
|
||||
- [[virtido]] — Sebastian's outsourcing company; its HR team is the webinar audience
|
||||
- [[inspectron]] — Eugene's employer (Edge Compute / IoT)
|
||||
|
||||
## Concepts
|
||||
|
||||
**Machine side**
|
||||
- [[harness]] — universal agent = LLM + small toolset + loop
|
||||
- [[skills-as-memory]] — git skills (SKILL.md + tools + data) as agent memory
|
||||
- [[evolution-of-agent-tooling]] — tools → MCP → skills
|
||||
- [[agentic-loops]] — inner (ReAct) / outer (Ralph) / meta
|
||||
- [[context-as-scarce-resource]] — the binding constraint; the "smart zone"
|
||||
- [[personal-ai-operating-system]] — Allie's context docs + skills + proactive workflows
|
||||
- [[levels-of-ai-usage]] — Eugene's ladder: chatbot → … → CLAUDE.md + skills (the non-programmer ceiling)
|
||||
- [[solve-first-then-skillify]] — solve the task once, then freeze it into a skill
|
||||
- [[integration-dead-ends]] — agent starts work against connectors the user's account doesn't have
|
||||
- [[leave-less-room-for-imagination]] — every gap in a spec gets filled, invisibly; tighten it
|
||||
|
||||
**Human side**
|
||||
- [[product-ownership]] — own outcomes, frame problems not tickets
|
||||
- [[connections-as-moat]] — in-person relationships as the last non-commoditized asset
|
||||
- [[network-from-a-standing-start]] — tentative from-zero networking protocol (v0, to be validated)
|
||||
- [[seniority-and-the-junior-squeeze]] — judgment as risk-reduction
|
||||
- [[decoupling-identity-from-profession]] — separate who you are from what you do
|
||||
|
||||
**Strategy side**
|
||||
- [[think-wider-not-bigger]] — breadth over depth; match ambition to the model
|
||||
- [[code-as-throwaway]] — cost of code → zero
|
||||
- [[make-more-cheap-code]] — Theo: four tiers of code; generate never-shipped slop to verify/explore; there's always another layer
|
||||
- [[enterprise-ai-reality]] — compliance lock-down; the company-managed-harness market
|
||||
|
||||
## Timelines
|
||||
|
||||
- [[ai-agent-evolution]] — agent/tooling timeline + Theo's model eras
|
||||
|
||||
## Comparisons
|
||||
|
||||
- [[theo-konstantin-allie]] — Theo vs Konstantin vs Allie: three lenses (strategy / engineering / personal-OS) on the same shift; shared markdown-as-unit and system-over-model, differing altitude
|
||||
|
||||
## Queries
|
||||
|
||||
- [[2026-07-14-best-first-skill-for-beginner]] — best first skill for a Claude beginner: skill-creator (meta) + tone-of-voice/anti-AI-language; foundation docs first
|
||||
- [[2026-07-14-network-from-standing-start]] — network-from-zero: tentative protocol + Sebastian round-2 interview instrument (10 questions)
|
||||
- [[2026-07-22-webinar-theses]] — 14 candidate theses for the webinar, grouped spine / stakes / obstacles / method / tensions
|
||||
- [[2026-07-24-non-engineer-throwaway-verification]] — non-engineer analog of throwaway verification code: generated checks not content; checker skills; drift as diagnostic
|
||||
|
||||
## Lint Reports
|
||||
|
||||
_None yet._
|
||||
# Wiki Index
|
||||
|
||||
Content catalog for this vault. Updated after every ingest / query / lint operation that changes the wiki.
|
||||
|
||||
See [[overview]] for the top-level synthesis and navigation.
|
||||
|
||||
Every wiki page carries a page-type tag under its H1 (`#source`, `#entity`, `#concept`, `#timeline`, `#comparison`, `#query`, `#lint-report`, `#overview`) — see "Tagging Rules" in `CLAUDE.md`.
|
||||
|
||||
## Sources
|
||||
|
||||
- [[2026-07-14-everything-we-knew-about-software-has-changed]] — Theo Browne (AIE): model eras, think wider, code as throwaway _(raw: Everything we knew about software has changed.md)_
|
||||
- [[2026-07-14-gap-between-ai-users-irreversible]] — Allie Miller: personal AI OS, foundation docs, skills, proactive workflows _(raw: In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md)_
|
||||
- [[2026-07-14-sebastian-eugene-interview]] — Sebastian + Eugene: harness, team collapse, connections, enterprise reality _(raw: sebastian interview - conclusions and insights.md)_
|
||||
- [[2026-07-14-skills-based-on-git]] — Konstantin (Sber): git skills as agent memory, harness, agent loops _(raw: Скиллы на базе git — новая память AI-агентов.md)_
|
||||
- [[2026-07-14-nina-interview]] — Eugene + Nina (HR): transcript > summary, friction not resistance, skills as handoff _(raw: Nina interview.md)_
|
||||
- [[2026-07-14-yulia-interview]] — Eugene + Yulia (HR lead): levels of AI usage, candidate knowledge base, solve-first _(raw: Yulia interview.md)_
|
||||
- [[2026-07-21-larysa-interview]] — Eugene + Larysa (BA/PM): memory loss, integration dead-ends, less room for imagination _(raw: Larysa interview.md)_
|
||||
- [[2026-07-22-ai-is-stupid]] — YouTube short (author unknown): "stupid AI" = model minus context minus harness; Nobel-vs-employee analogy _(raw: ИИ глупый!.md)_
|
||||
- [[2026-07-24-youre-reading-way-too-much-code]] — Theo Browne (video): make more cheap code, four tiers of code, 100:1 slop-to-ship verification _(raw: You're reading way too much code.md)_
|
||||
|
||||
**Raw, not yet ingested:** `raw/sources/Agentic Engineering, explained by a 10x developer.md` · `raw/sources/Webinar Plan - From Chat Box to Your Own OS.md` · `raw/sources/Webinar script.md`
|
||||
|
||||
## Coverage
|
||||
|
||||
- [[script-coverage]] — every concept vs `raw/sources/Webinar script.md`; 5 covered, 4 partial, 10 absent
|
||||
|
||||
## Entities
|
||||
|
||||
### People
|
||||
- [[theo-browne]] — developer/educator (t3.gg); "think wider", "make more cheap code"
|
||||
- [[allie-miller]] — ex-Amazon AI leader; personal AI OS
|
||||
- [[sebastian]] — founder of Virtido; enterprise/connections lens
|
||||
- [[eugene]] — developer, harness-builder, webinar author; interviewer (likely vault owner, tentative)
|
||||
- [[konstantin]] — Sber/GigaChat R&D; skills-as-memory
|
||||
- [[nina]] — HR recruiter at Virtido; webinar-audience proxy, use-case supplier
|
||||
- [[yulia]] — HR/recruiting lead; webinar organizer (name/affiliation tentative)
|
||||
- [[larysa]] — technical BA/PM, ex-mobile dev; advanced user blocked by memory + integrations
|
||||
|
||||
### Tools / Orgs
|
||||
- [[claude-code]] — reference harness (all sources)
|
||||
- [[hermes]] — skills-first, self-curating harness
|
||||
- [[virtido]] — Sebastian's outsourcing company; its HR team is the webinar audience
|
||||
- [[inspectron]] — Eugene's employer (Edge Compute / IoT)
|
||||
|
||||
## Concepts
|
||||
|
||||
**Machine side**
|
||||
- [[harness]] — universal agent = LLM + small toolset + loop
|
||||
- [[skills-as-memory]] — git skills (SKILL.md + tools + data) as agent memory
|
||||
- [[evolution-of-agent-tooling]] — tools → MCP → skills
|
||||
- [[agentic-loops]] — inner (ReAct) / outer (Ralph) / meta
|
||||
- [[context-as-scarce-resource]] — the binding constraint; the "smart zone"
|
||||
- [[personal-ai-operating-system]] — Allie's context docs + skills + proactive workflows
|
||||
- [[levels-of-ai-usage]] — Eugene's ladder: chatbot → … → CLAUDE.md + skills (the non-programmer ceiling)
|
||||
- [[solve-first-then-skillify]] — solve the task once, then freeze it into a skill
|
||||
- [[integration-dead-ends]] — agent starts work against connectors the user's account doesn't have
|
||||
- [[leave-less-room-for-imagination]] — every gap in a spec gets filled, invisibly; tighten it
|
||||
|
||||
**Human side**
|
||||
- [[product-ownership]] — own outcomes, frame problems not tickets
|
||||
- [[connections-as-moat]] — in-person relationships as the last non-commoditized asset
|
||||
- [[network-from-a-standing-start]] — tentative from-zero networking protocol (v0, to be validated)
|
||||
- [[seniority-and-the-junior-squeeze]] — judgment as risk-reduction
|
||||
- [[decoupling-identity-from-profession]] — separate who you are from what you do
|
||||
|
||||
**Strategy side**
|
||||
- [[think-wider-not-bigger]] — breadth over depth; match ambition to the model
|
||||
- [[code-as-throwaway]] — cost of code → zero
|
||||
- [[make-more-cheap-code]] — Theo: four tiers of code; generate never-shipped slop to verify/explore; there's always another layer
|
||||
- [[enterprise-ai-reality]] — compliance lock-down; the company-managed-harness market
|
||||
|
||||
## Timelines
|
||||
|
||||
- [[ai-agent-evolution]] — agent/tooling timeline + Theo's model eras
|
||||
|
||||
## Comparisons
|
||||
|
||||
- [[theo-konstantin-allie]] — Theo vs Konstantin vs Allie: three lenses (strategy / engineering / personal-OS) on the same shift; shared markdown-as-unit and system-over-model, differing altitude
|
||||
|
||||
## Queries
|
||||
|
||||
- [[2026-07-14-best-first-skill-for-beginner]] — best first skill for a Claude beginner: skill-creator (meta) + tone-of-voice/anti-AI-language; foundation docs first
|
||||
- [[2026-07-14-network-from-standing-start]] — network-from-zero: tentative protocol + Sebastian round-2 interview instrument (10 questions)
|
||||
- [[2026-07-22-webinar-theses]] — 14 candidate theses for the webinar, grouped spine / stakes / obstacles / method / tensions
|
||||
- [[2026-07-24-non-engineer-throwaway-verification]] — non-engineer analog of throwaway verification code: generated checks not content; checker skills; drift as diagnostic
|
||||
|
||||
## Lint Reports
|
||||
|
||||
_None yet._
|
||||
|
||||
314
log.md
314
log.md
@@ -1,157 +1,157 @@
|
||||
# Operation Log
|
||||
|
||||
Append-only chronological record of wiki operations. Newest entries at the bottom.
|
||||
|
||||
Entry format:
|
||||
|
||||
```
|
||||
## YYYY-MM-DD — <operation>
|
||||
- Intent: ingest | query | lint | maintenance | sync
|
||||
- Input: <source path / question / scope>
|
||||
- Pages changed: [[...]], [[...]]
|
||||
- Notes: <what changed, uncertainty, next steps>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-14 — maintenance
|
||||
- Intent: maintenance
|
||||
- Input: Initialize vault folder structure.
|
||||
- Pages changed: created `index.md`, `log.md`, `wiki/overview.md`; created `raw/{sources,assets}` and `wiki/{sources,entities,concepts,timelines,comparisons,queries,lint-reports}`.
|
||||
- Notes: Empty vault scaffolded per the LLM Wiki Schema in `CLAUDE.md`. No sources ingested yet. Ready for first "ingest <source>".
|
||||
|
||||
## 2026-07-14 — ingest (batch, 4 sources)
|
||||
- Intent: ingest
|
||||
- Input: The 4 talk/interview docs (user-selected scope; "Ideas for webinar" + "HR Contacts" left as raw reference).
|
||||
- `raw/sources/Everything we knew about software has changed.md`
|
||||
- `raw/sources/In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md`
|
||||
- `raw/sources/sebastian interview - conclusions and insights.md`
|
||||
- `raw/sources/Скиллы на базе git — новая память AI-агентов.md`
|
||||
- Pages created — sources (4): [[2026-07-14-everything-we-knew-about-software-has-changed]], [[2026-07-14-gap-between-ai-users-irreversible]], [[2026-07-14-sebastian-eugene-interview]], [[2026-07-14-skills-based-on-git]].
|
||||
- Pages created — entities (8): [[theo-browne]], [[allie-miller]], [[sebastian]], [[eugene]], [[konstantin]], [[claude-code]], [[hermes]], [[virtido]].
|
||||
- Pages created — concepts (13): [[harness]], [[skills-as-memory]], [[evolution-of-agent-tooling]], [[agentic-loops]], [[context-as-scarce-resource]], [[personal-ai-operating-system]], [[product-ownership]], [[connections-as-moat]], [[seniority-and-the-junior-squeeze]], [[decoupling-identity-from-profession]], [[think-wider-not-bigger]], [[code-as-throwaway]], [[enterprise-ai-reality]].
|
||||
- Pages created — timelines (1): [[ai-agent-evolution]].
|
||||
- Pages updated: [[overview]] (added the cross-source through-line + agree/diverge), `index.md` (full catalog).
|
||||
- Notes: Strong cross-source convergence (skills-as-memory: Konstantin ↔ Allie; connections: Sebastian ↔ Allie; code-as-throwaway: Theo ↔ Sebastian). Recorded contradictions (Eugene vs Sebastian on BYO- vs company-managed harness, online vs in-person networking, OSS motivation). Tentative claims flagged: Theo's model-era names, Eugene = vault owner, Hermes/Ralph heuristics, Allie's self-learning-models prediction.
|
||||
- Next: consider ingesting "Ideas for webinar" (connects corpus → webinar plan) and "HR Contacts" (the HR-search demo); consider a `wiki/comparisons/` page for the BYO-vs-managed-harness debate; run "lint wiki" to check link health.
|
||||
|
||||
## 2026-07-14 — maintenance (tagging convention)
|
||||
- Intent: maintenance
|
||||
- Input: user request — add per-type hashtags to the wiki schema and existing pages.
|
||||
- Pages changed: `CLAUDE.md` (new "Tagging Rules" section, rule 9, templates + lint checklist updated); all 26 wiki pages received a page-type tag line under their H1 — [[overview]] `#overview`, 4 source pages `#source`, 8 entity pages `#entity`, 13 concept pages `#concept`, [[ai-agent-evolution]] `#timeline`; `index.md` (noted the convention).
|
||||
- Notes: Tag mapping is folder-driven (`#source`, `#entity`, `#concept`, `#timeline`, `#comparison`, `#query`, `#lint-report`, `#overview`). Exactly one type tag per page, first on the tag line; topical tags may follow. Lint now checks for missing/mismatched type tags.
|
||||
|
||||
## 2026-07-14 -- query
|
||||
- Intent: query
|
||||
- Input: "what would be the best claude skill to give to a claude beginner user?"
|
||||
- Pages changed: created [[2026-07-14-best-first-skill-for-beginner]]; updated [[skills-as-memory]] (Next Questions item answered + linked), `index.md` (Queries section).
|
||||
- Notes: Answer synthesized from Allie Miller (skill-creator, tone-of-voice/anti-AI-language starter set, foundation-docs-first) and Konstantin (>5-tool-calls auto-creation heuristic). Follow-up: contents of a good tone-of-voice SKILL.md; foundation-doc templates.
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit)
|
||||
- Intent: maintenance
|
||||
- Input: user explicitly authorized editing `raw/sources/Webinar script.md` this session (exception to rule 1).
|
||||
- Pages changed: `raw/sources/Webinar script.md` — completed the dangling Tools→Memory bridge line, wrote the full **# Memory** section (amnesia demo → notebook tool → close/reopen payoff → system-prompt reveal → user.md beat → tiny-notebook limitation as the Skills hook), and renamed "Markus" → "Marcus" to match the demo app's seeded mail (`Marcus Hale`).
|
||||
- Notes: Memory section is grounded in the actual mini-game behavior (Level 04 in `D:\Projects\Names\Webinars\From_chat_to_os`): frozen snapshot per session (hence the mandatory close/reopen), `memory.md` + `user.md` on disk, ~2200-char budget motivating Skills. No wiki pages changed. Next: draft **# Skills** section (open with on-demand loading answering the phone-book limitation).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, Skills section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — draft the **# Skills** section in `raw/sources/Webinar script.md` (edit permission granted this session). Corrected flow per user: presenter dictates the operations step by step first, *then* asks AI to package the procedure as a skill.
|
||||
- Pages changed: `raw/sources/Webinar script.md` — full Skills section (step-by-step dictation → "I was the recipe" → save-as-skill → SKILL.md on disk → fresh-session one-liner → progressive-disclosure reveal → portability beat → "I'm still the alarm clock" hook into Process).
|
||||
- Notes: Grounded in the app's Skills level (Level 05): `save_skill`/`load_skill`, real `skills/<name>/SKILL.md`, live menu (names+descriptions only) rebuilt per window. No wiki pages changed. Next: draft **# Process** (Level 06 — spawn_process scheduler answers the alarm-clock limitation).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, Process section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — draft the **# Process** section in `raw/sources/Webinar script.md` (session edit permission).
|
||||
- Pages changed: `raw/sources/Webinar script.md` — full Process section (goal not task → spawn_process with pid → hands-off heartbeats → Override slider makes the cube move by itself → ps/kill → reveal: the shell authored the worker's prompt (AI managing AI) → closing arc: same model all six levels, only the harness grew; harness is unique to you; "from a chat box to your own Agentic Operating System"). Also two-branch rule fixes earlier this session (Memory convention + Skills dictation).
|
||||
- Notes: Grounded in Level 06 design (`2026-07-11-process-level-design.md`): single ~5s scheduler, stateless ticks, spawn/list/stop syscalls, live −5…+5 weather offset. The "same model, growing harness" close absorbs the `_ideas:` note at the top of the script. Script now has all sections drafted (Intro → Process).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, OS section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — add an **# OS** section to `raw/sources/Webinar script.md` (session edit permission): typing removed, mouse-only interaction with the agent.
|
||||
- Pages changed: `raw/sources/Webinar script.md` — Process now ends with a "still a terminal / most people never will type" hook; new OS section (one-button app → rule baked in → 5-second checkbox → appliance → "the agent became a program / the chat box dissolved into the OS"); the "same model, growing harness" closing arc moved from Process into OS, with the new final callback "a button that already knows what the email said."
|
||||
- Notes: Grounded in the OS app design (`2026-07-12-os-app-design.md`): tile 07, status bar mirrors the agent's closing sentence, shared scheduler slot, Override interplay, rule baked into the prompt. Script ladder now: Chat box → ReAct → Tools → Memory → Skills → Process → OS.
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, OS reframing)
|
||||
- Intent: maintenance
|
||||
- Input: user correction — the webinar's core idea is "make tools for yourself," not "become a product."
|
||||
- Pages changed: `raw/sources/Webinar script.md` — Process→OS hook now ends "…and become a tool? A small one. Made for exactly one person."; OS landing gained the intro callback (weekends burned on internal tools → this one took an evening, asked-for not written) and "It dissolved — into the operating system. Into little tools you make for yourself."; closing arc adds "You don't buy it. You build it — one small tool at a time."
|
||||
- Notes: The OS section now closes the loop with the Intro's internal-tools passion. No wiki pages changed.
|
||||
|
||||
## 2026-07-14 — ingest (batch, 2 sources: Nina + Yulia interviews)
|
||||
- Intent: ingest
|
||||
- Input: `raw/sources/Nina interview.md`, `raw/sources/Yulia interview.md` (both are conclusions docs auto-generated by Eugene's record→diarize→transcribe→summarize tool).
|
||||
- Pages created — sources (2): [[2026-07-14-nina-interview]], [[2026-07-14-yulia-interview]].
|
||||
- Pages created — entities (3): [[nina]] (HR recruiter, Virtido), [[yulia]] (HR lead; name/affiliation tentative, inferred from filename + Nina reference), [[inspectron]] (Eugene's employer).
|
||||
- Pages created — concepts (2): [[levels-of-ai-usage]] (chatbot → memory → Claude Code → CLAUDE.md → skills → KB → RAG; non-programmer ceiling = CLAUDE.md + skills), [[solve-first-then-skillify]] (solve once, then freeze into a skill; ~3-message and >5-tool-call heuristics).
|
||||
- Pages updated: [[eugene]] (identity evidence strengthened — webinar author/presenter, Inspectron, $200 max plan, tool builder; still tentative), [[virtido]] (HR team = webinar audience, pain points, tooling), [[skills-as-memory]] (handoff/de-risking payoff, ~3-message heuristic, method link), [[connections-as-moat]] (Eugene independently converges: "the human's role is just to be human"), [[overview]] (6 sources, demand-side bullet, agree/diverge, navigation, open questions), `index.md`.
|
||||
- Notes: Strong convergence — Eugene ↔ Sebastian/Allie on human-connection residual despite their networking-tactics disagreement; Eugene's ~3-message heuristic ↔ Konstantin's >5-tool-call heuristic. New cross-interview finding: adoption blocked by friction, not resistance. Tentative flags: Yulia's name/affiliation; Eugene's price-rise prediction; Inspectron employment-vs-contracting. Skills-IP-vs-work-product dispute (Eugene vs Sebastian) recorded, unresolved.
|
||||
- Next: ingest "Ideas for webinar" / "Webinar Plan" / "Webinar script" to connect corpus → deliverable; interview Larysa/Larisa (PM use cases, twice flagged); consider a comparison page "personal vs employer ownership of skills".
|
||||
|
||||
## 2026-07-14 — query (network from a standing start)
|
||||
- Intent: query
|
||||
- Input: "how does an individual actually build a network from a standing start?" + "go" on the recommended plan (tentative protocol + Sebastian follow-up instrument).
|
||||
- Pages created: [[network-from-a-standing-start]] (concept, Status: tentative — 5-step protocol: recurring venues → cadence → lead with humanness → engineer second meetings → track second meetings/let referrals work; contested anti-tactics list; webinar flagged as live case study), [[2026-07-14-network-from-standing-start]] (query — 10-question Sebastian round-2 interview instrument in 3 blocks: bootstrap biography / mechanics / falsification of "Big zero").
|
||||
- Pages updated: [[connections-as-moat]] (open question → protocol + validation plan), [[overview]] (vault-level open question annotated), `index.md` (Concepts + Queries sections).
|
||||
- Notes: Corpus cannot answer the question directly — protocol is inferred from Sebastian's principles, Allie's prediction, and Eugene's convergent thesis; every claim marked tentative/contested. Key falsification target: whether Sebastian ever had a true standing start (prior-job network as seed). Deep-research complement (weak ties, mere exposure, from-zero playbooks, scoped to test "Big zero") described but not run.
|
||||
- Next: run the round-2 Sebastian interview and ingest it; decide on the deep-research run; track webinar → paid-HR-build chain as case-study evidence.
|
||||
|
||||
## 2026-07-16 — query → comparison
|
||||
- Intent: query
|
||||
- Input: "Compare Theo's, Konstantin's ('Sonstantine') and Allie's approaches — what they have in common, what they have different?"
|
||||
- Pages created: [[theo-konstantin-allie]] (first `wiki/comparisons/` page — three-lens side-by-side: at-a-glance table, 6 shared points, differences by altitude/framing/code/learning/register, complementary tensions).
|
||||
- Pages updated: [[theo-browne]], [[konstantin]], [[allie-miller]] (added inbound "Comparison:" links to avoid orphan); `index.md` (Comparisons section — first entry).
|
||||
- Notes: Synthesized from the 3 source summaries + entity pages + [[skills-as-memory]]. Common ground: bottleneck moved model→human system; markdown/skills as the atomic unit; infrastructure compounds; system-ready to absorb new models; context as scarce resource; shared [[claude-code]]. Differences framed as *altitude* (Theo strategy/psychology · Konstantin engineering · Allie individual-productivity), not direction — corpus disagreements lie elsewhere. Recorded the throwaway-code (Theo) vs persist-in-git (Konstantin) tension as complementary (artifact vs capability). No new contradictions. Saved as a comparison rather than a query page since the request was explicitly a side-by-side.
|
||||
- Next: reusable starter template (foundation docs / good SKILL.md) still unresolved across all three — webinar-relevant; consider whether Konstantin's meta-loop (wipe-and-restart) tensions with "persist everything".
|
||||
|
||||
## 2026-07-16 — maintenance (table fix)
|
||||
- Intent: maintenance
|
||||
- Input: user report — the table in [[ai-agent-evolution]] "looks broken".
|
||||
- Pages changed: [[ai-agent-evolution]] — repaired the "Agent architecture & tooling (Konstantin)" table; escaped the `|` inside aliased wiki links (`[[harness\|harnesses]]`, `[[skills-as-memory\|skills]]`, `[[agentic-loops\|agent loops]]`) so Obsidian no longer reads them as column separators, and removed the two phantom trailing columns the unescaped pipes had forced into the header/separator. Now a clean 3-column table (Period / Milestone / Significance).
|
||||
- Notes: Content unchanged — formatting-only fix. The Theo Browne table was already valid. No `index.md` change (no catalog/structural change). Root cause: piped `[[page|alias]]` links inside GFM/Obsidian table cells require the pipe escaped as `\|`.
|
||||
|
||||
## 2026-07-21 — ingest (Larysa interview)
|
||||
- Intent: ingest
|
||||
- Input: "ingest Larysa interview.md" → `raw/sources/Larysa interview.md` (auto-generated interview conclusions doc; Eugene × Larysa, technical BA/PM and ex-mobile dev).
|
||||
- Pages created: [[2026-07-21-larysa-interview]] (source), [[larysa]] (entity), [[integration-dead-ends]] (concept — agent begins work against connectors gated by account tier / paid seat / missing API; corpus offers no fix, only up-front verification), [[leave-less-room-for-imagination]] (concept — under-specified prompts drift and the collateral damage is *invisible*; skills as the constraint; includes the 4.7-over-4.8 model-choice corollary).
|
||||
- Pages updated: [[skills-as-memory]] (new "negative case" section — built-in memory as anti-feature, the demand-side reason skills exist; contradiction logged vs Allie), [[harness]] (consolidation-over-tool-hopping section + "before and after" claim marked self-reported), [[code-as-throwaway]] (auth/payments trust carve-out; "safe from 4.6 on"), [[levels-of-ai-usage]] (Larysa as proof the rungs are skippable — technically advanced, architecturally stuck), [[claude-code]] (practitioner-limits section: memory, connectors, 4.6/4.7/4.8, emulator), [[solve-first-then-skillify]], [[personal-ai-operating-system]] (cross-ref to Eugene's convergent OS framing), [[eugene]], [[yulia]] (Larisa open question partially resolved), [[virtido]] (audience extends beyond HR; ClickUp/Figma/Teams/Slack), [[overview]] (6→7 sources, demand-side paragraph, two new divergences, two new vault-level open questions), `index.md`.
|
||||
- Notes: Closes the "Larysa/Larisa not yet interviewed — PM use cases missing" gap flagged in both HR interviews. Key reframe for the webinar: this source moves the diagnosis from *friction* (Nina/Yulia: people would adopt if it were simple) to *structural walls* for users already past friction — memory, entitlements, drift. Two genuine corpus contradictions recorded rather than smoothed: memory-as-anti-feature (Eugene) vs Allie's untroubled use of persistent context docs, and tight-spec vs [[think-wider-not-bigger]]. Also corrected `index.md`: `HR Contacts.md` was listed as not-yet-ingested but does not exist in `raw/sources/` — removed from the list.
|
||||
- Next: remaining un-ingested raw are the three webinar-deliverable docs (`Ideas for webinar.md`, `Webinar Plan - From Chat Box to Your Own OS.md`, `Webinar script.md`) — ingesting them would connect the corpus to the actual deliverable and settle whether the script keeps the [[levels-of-ai-usage]] rung order. Candidate query: does the skills rung actually answer Larysa's memory complaint, or is hers a cross-project problem skills don't solve? A first lint pass is also overdue (no lint reports exist; 7 sources, 17 concepts).
|
||||
|
||||
## 2026-07-22 — query (webinar theses)
|
||||
- Intent: query
|
||||
- Input: "What theses can I suggest for the webinar ('from chatbox to your own agentic operating system') based on what you already have?"
|
||||
- Pages changed: created [[2026-07-22-webinar-theses]]; updated `index.md` (Queries section).
|
||||
- Notes: 14 candidate theses synthesized from [[overview]], the 7 source summaries, and direct reads of the three raw webinar-deliverable docs (Plan, script, Ideas — still raw-only, cited as raw per policy). Grouped: spine (harness-not-model, app-you-open→OS, skills-as-memory, context scarcity, build-not-buy) / stakes (cost→zero, irreversible gap, connections rise) / obstacles (friction-not-resistance, structural walls, less-room-for-imagination) / method (solve-first-then-skillify, research-vs-judgment, walk-in-a-week) / honest tensions (3 recorded contradictions offered as Q&A ammo). Recommended 7-thesis subset for the 30-min format noted in the query page. No concept/entity pages changed.
|
||||
- Next: ingest the three deliverable docs so theses can cite wiki sources instead of raw; decide whether the "obstacles" theses earn a station on the spine.
|
||||
|
||||
## 2026-07-22 — ingest (ИИ глупый! short)
|
||||
- Intent: ingest
|
||||
- Input: "ingest \"ИИ глупый!\"" → `raw/sources/ИИ глупый!.md` (conclusions doc for a 1:28 Russian YouTube Short, author unknown; file was added mid-session after the first lookup found nothing).
|
||||
- Pages created: [[2026-07-22-ai-is-stupid]] (source).
|
||||
- Pages updated: [[harness]] (business-facing "engineering wrapper" definition + model+context+harness formula, flagged as webinar language), [[context-as-scarce-resource]] (supply-side facet: "intelligence without context loses to context without intelligence", Nobel-vs-employee analogy; RAG-vs-skills tension logged under Contradictions), [[overview]] (7→8 sources, convergence one-liner, navigation), `index.md` (Sources entry; `my theses.md` added to the not-yet-ingested list).
|
||||
- Notes: No new concepts — the short *restates* the vault's machine-side spine for a business audience, which makes it webinar-quotable rather than novel. One tension recorded, not smoothed: it recommends RAG/long-term memory as context mechanisms where Konstantin argues skills beat RAG (possibly audience-driven — business data vs procedures). Authorship unknown and marked tentative; its framing matches the corpus closely enough that a connection to someone already in the corpus is worth checking. All ×10…×1000 gain claims are rhetorical, not measured.
|
||||
- Next: `my theses.md` is new in raw and un-ingested (six webinar thesis one-liners) — small, high-relevance ingest candidate; the three webinar-deliverable docs remain pending; first lint pass still overdue (8 sources, 17 concepts, 0 lint reports).
|
||||
|
||||
## 2026-07-24 — ingest (You're reading way too much code)
|
||||
- Intent: ingest
|
||||
- Input: "ingest \"You're reading way too much code\"" → `raw/sources/You're reading way too much code.md` (conclusions doc for Theo Browne's 24:11 video; his second source in the vault).
|
||||
- Pages created: [[2026-07-24-youre-reading-way-too-much-code]] (source), [[make-more-cheap-code]] (concept — ship/no-ship line, four tiers of code A–D, 100–10,000:1 slop-to-ship verification ratio, always-another-layer, dumb-model agents as API usability testers, reading-costs-attention economics).
|
||||
- Pages updated: [[code-as-throwaway]] (discipline section; evidence; its "what is the durable artifact" open question partially answered — the verification harness is now a named first-class output), [[theo-browne]] (second talk, recurring author-move noted, self-reported ratios flagged tentative), [[leave-less-room-for-imagination]] (new logged tension: Theo/Dax agent-diff-summaries vs Eugene's invisible-drift claim), [[2026-07-14-everything-we-knew-about-software-has-changed]] (reciprocal related-source link), [[overview]] (8→9 sources; verifying-half of spine given its method; new divergence line; 17→18 concepts), `index.md` (Sources, People, Concepts entries).
|
||||
- Notes: The source is a *defense with discipline*, not a reversal — Theo explicitly rejects shipping unreviewed slop, which pre-empts the obvious objection to [[code-as-throwaway]]. Strong webinar relevance: "attention, not generation, is the bottleneck" is the engineer-side twin of [[context-as-scarce-resource]], and the tier framework gives audiences a non-binary answer to "can I trust AI code?". One genuine tension recorded rather than smoothed (summaries-hide-drift). Shao's 80%-into-harnesses ratio and all of Theo's daily-line counts are self-reported/uncited — marked tentative. Open framework gap flagged: skills/CLAUDE.md files don't fit the A–D spectrum.
|
||||
- Next: candidate query — what is the non-engineer's analog of throwaway verification code (HR/BA audience)? `my theses.md` and the three webinar-deliverable docs remain un-ingested; first lint pass still overdue (9 sources, 18 concepts, 0 lint reports).
|
||||
|
||||
## 2026-07-24 — query (non-engineer throwaway verification)
|
||||
- Intent: query
|
||||
- Input: "query: what is the non-engineer's analog of throwaway verification code?" (the candidate query flagged in the previous ingest).
|
||||
- Pages created: [[2026-07-24-non-engineer-throwaway-verification]] (query — answer: disposable AI work that attacks/misreads/simulates the deliverable before a human sees it; one-to-one mapping table from Theo's engineer patterns to HR/BA use cases; "checker skills" as the second species of skill; tier-D-stays-human caveat since non-engineer verification bottoms out in judgment, not tests).
|
||||
- Pages updated: [[make-more-cheap-code]] (next-question marked answered, link added), [[leave-less-room-for-imagination]] (new next-question: drift harnessed as a sandboxed ambiguity diagnostic — synthesis, tentative), `index.md` (Queries section).
|
||||
- Notes: Pure synthesis, no new source — every mapped pattern is grounded in corpus use cases (Nina/Yulia job descriptions, candidate KB, sourcing; Larysa spec ambiguity; Allie's anti-AI-language checker-skill precedent). Key reframes with durable value: (1) the fresh-agent misread test inverts [[leave-less-room-for-imagination]] — drift becomes a diagnostic when sandboxed; (2) [[solve-first-then-skillify]] populates skills in two species, producers and checkers. Flagged honestly: the whole mapping is argument-by-analogy with no measured claim; Nina's transcript-beats-summary finding is a standing counterweight to summary-based review.
|
||||
- Next: decide whether "checker skills" earns a slide on the webinar's skills rung; the webinar-deliverable docs (`Ideas`, `Plan`, `script`, `my theses.md`) remain un-ingested; first lint pass still overdue (9 sources, 18 concepts, 2026-07-24 now has 1 query, 0 lint reports).
|
||||
|
||||
## 2026-07-28 — sync (script coverage, initial)
|
||||
- Intent: sync script coverage
|
||||
- Input: first run of Workflow D, establishing `wiki/script-coverage.md`.
|
||||
- Pages created: [[script-coverage]] (coverage) — 19 rows, one per concept page.
|
||||
- Pages updated: `CLAUDE.md` (folder convention, `#coverage` tag row, Workflow D, new intent), `index.md` (new Coverage section; corrected the not-yet-ingested list — `Ideas for webinar.md` and `my theses.md` were listed under `raw/sources/` but live in `raw/notes/`, and `Agentic Engineering, explained by a 10x developer.md` was missing entirely).
|
||||
- Notes: Initial assessment is 5 covered, 4 partial, 10 absent. Eight of the ten absent are human-side or strategy-side per the grouping in index.md; the other two — [[integration-dead-ends]] and [[leave-less-room-for-imagination]] — are machine-side, absent because the script demos the happy path and never reaches connector gating or spec ambiguity. The `ReAct` station carries no wiki concept. No concept pages were edited.
|
||||
- Next: decide whether the human-side cluster earns a station or is a deliberate cut; decide separately whether the two absent machine-side failure modes belong in the demo; pin the rows that are decided so future syncs leave them alone.
|
||||
# Operation Log
|
||||
|
||||
Append-only chronological record of wiki operations. Newest entries at the bottom.
|
||||
|
||||
Entry format:
|
||||
|
||||
```
|
||||
## YYYY-MM-DD — <operation>
|
||||
- Intent: ingest | query | lint | maintenance | sync
|
||||
- Input: <source path / question / scope>
|
||||
- Pages changed: [[...]], [[...]]
|
||||
- Notes: <what changed, uncertainty, next steps>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 2026-07-14 — maintenance
|
||||
- Intent: maintenance
|
||||
- Input: Initialize vault folder structure.
|
||||
- Pages changed: created `index.md`, `log.md`, `wiki/overview.md`; created `raw/{sources,assets}` and `wiki/{sources,entities,concepts,timelines,comparisons,queries,lint-reports}`.
|
||||
- Notes: Empty vault scaffolded per the LLM Wiki Schema in `CLAUDE.md`. No sources ingested yet. Ready for first "ingest <source>".
|
||||
|
||||
## 2026-07-14 — ingest (batch, 4 sources)
|
||||
- Intent: ingest
|
||||
- Input: The 4 talk/interview docs (user-selected scope; "Ideas for webinar" + "HR Contacts" left as raw reference).
|
||||
- `raw/sources/Everything we knew about software has changed.md`
|
||||
- `raw/sources/In 1 Year, the Gap Between AI Users and Everyone Else Will Be Irreversible.md`
|
||||
- `raw/sources/sebastian interview - conclusions and insights.md`
|
||||
- `raw/sources/Скиллы на базе git — новая память AI-агентов.md`
|
||||
- Pages created — sources (4): [[2026-07-14-everything-we-knew-about-software-has-changed]], [[2026-07-14-gap-between-ai-users-irreversible]], [[2026-07-14-sebastian-eugene-interview]], [[2026-07-14-skills-based-on-git]].
|
||||
- Pages created — entities (8): [[theo-browne]], [[allie-miller]], [[sebastian]], [[eugene]], [[konstantin]], [[claude-code]], [[hermes]], [[virtido]].
|
||||
- Pages created — concepts (13): [[harness]], [[skills-as-memory]], [[evolution-of-agent-tooling]], [[agentic-loops]], [[context-as-scarce-resource]], [[personal-ai-operating-system]], [[product-ownership]], [[connections-as-moat]], [[seniority-and-the-junior-squeeze]], [[decoupling-identity-from-profession]], [[think-wider-not-bigger]], [[code-as-throwaway]], [[enterprise-ai-reality]].
|
||||
- Pages created — timelines (1): [[ai-agent-evolution]].
|
||||
- Pages updated: [[overview]] (added the cross-source through-line + agree/diverge), `index.md` (full catalog).
|
||||
- Notes: Strong cross-source convergence (skills-as-memory: Konstantin ↔ Allie; connections: Sebastian ↔ Allie; code-as-throwaway: Theo ↔ Sebastian). Recorded contradictions (Eugene vs Sebastian on BYO- vs company-managed harness, online vs in-person networking, OSS motivation). Tentative claims flagged: Theo's model-era names, Eugene = vault owner, Hermes/Ralph heuristics, Allie's self-learning-models prediction.
|
||||
- Next: consider ingesting "Ideas for webinar" (connects corpus → webinar plan) and "HR Contacts" (the HR-search demo); consider a `wiki/comparisons/` page for the BYO-vs-managed-harness debate; run "lint wiki" to check link health.
|
||||
|
||||
## 2026-07-14 — maintenance (tagging convention)
|
||||
- Intent: maintenance
|
||||
- Input: user request — add per-type hashtags to the wiki schema and existing pages.
|
||||
- Pages changed: `CLAUDE.md` (new "Tagging Rules" section, rule 9, templates + lint checklist updated); all 26 wiki pages received a page-type tag line under their H1 — [[overview]] `#overview`, 4 source pages `#source`, 8 entity pages `#entity`, 13 concept pages `#concept`, [[ai-agent-evolution]] `#timeline`; `index.md` (noted the convention).
|
||||
- Notes: Tag mapping is folder-driven (`#source`, `#entity`, `#concept`, `#timeline`, `#comparison`, `#query`, `#lint-report`, `#overview`). Exactly one type tag per page, first on the tag line; topical tags may follow. Lint now checks for missing/mismatched type tags.
|
||||
|
||||
## 2026-07-14 -- query
|
||||
- Intent: query
|
||||
- Input: "what would be the best claude skill to give to a claude beginner user?"
|
||||
- Pages changed: created [[2026-07-14-best-first-skill-for-beginner]]; updated [[skills-as-memory]] (Next Questions item answered + linked), `index.md` (Queries section).
|
||||
- Notes: Answer synthesized from Allie Miller (skill-creator, tone-of-voice/anti-AI-language starter set, foundation-docs-first) and Konstantin (>5-tool-calls auto-creation heuristic). Follow-up: contents of a good tone-of-voice SKILL.md; foundation-doc templates.
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit)
|
||||
- Intent: maintenance
|
||||
- Input: user explicitly authorized editing `raw/sources/Webinar script.md` this session (exception to rule 1).
|
||||
- Pages changed: `raw/sources/Webinar script.md` — completed the dangling Tools→Memory bridge line, wrote the full **# Memory** section (amnesia demo → notebook tool → close/reopen payoff → system-prompt reveal → user.md beat → tiny-notebook limitation as the Skills hook), and renamed "Markus" → "Marcus" to match the demo app's seeded mail (`Marcus Hale`).
|
||||
- Notes: Memory section is grounded in the actual mini-game behavior (Level 04 in `D:\Projects\Names\Webinars\From_chat_to_os`): frozen snapshot per session (hence the mandatory close/reopen), `memory.md` + `user.md` on disk, ~2200-char budget motivating Skills. No wiki pages changed. Next: draft **# Skills** section (open with on-demand loading answering the phone-book limitation).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, Skills section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — draft the **# Skills** section in `raw/sources/Webinar script.md` (edit permission granted this session). Corrected flow per user: presenter dictates the operations step by step first, *then* asks AI to package the procedure as a skill.
|
||||
- Pages changed: `raw/sources/Webinar script.md` — full Skills section (step-by-step dictation → "I was the recipe" → save-as-skill → SKILL.md on disk → fresh-session one-liner → progressive-disclosure reveal → portability beat → "I'm still the alarm clock" hook into Process).
|
||||
- Notes: Grounded in the app's Skills level (Level 05): `save_skill`/`load_skill`, real `skills/<name>/SKILL.md`, live menu (names+descriptions only) rebuilt per window. No wiki pages changed. Next: draft **# Process** (Level 06 — spawn_process scheduler answers the alarm-clock limitation).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, Process section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — draft the **# Process** section in `raw/sources/Webinar script.md` (session edit permission).
|
||||
- Pages changed: `raw/sources/Webinar script.md` — full Process section (goal not task → spawn_process with pid → hands-off heartbeats → Override slider makes the cube move by itself → ps/kill → reveal: the shell authored the worker's prompt (AI managing AI) → closing arc: same model all six levels, only the harness grew; harness is unique to you; "from a chat box to your own Agentic Operating System"). Also two-branch rule fixes earlier this session (Memory convention + Skills dictation).
|
||||
- Notes: Grounded in Level 06 design (`2026-07-11-process-level-design.md`): single ~5s scheduler, stateless ticks, spawn/list/stop syscalls, live −5…+5 weather offset. The "same model, growing harness" close absorbs the `_ideas:` note at the top of the script. Script now has all sections drafted (Intro → Process).
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, OS section)
|
||||
- Intent: maintenance
|
||||
- Input: user request — add an **# OS** section to `raw/sources/Webinar script.md` (session edit permission): typing removed, mouse-only interaction with the agent.
|
||||
- Pages changed: `raw/sources/Webinar script.md` — Process now ends with a "still a terminal / most people never will type" hook; new OS section (one-button app → rule baked in → 5-second checkbox → appliance → "the agent became a program / the chat box dissolved into the OS"); the "same model, growing harness" closing arc moved from Process into OS, with the new final callback "a button that already knows what the email said."
|
||||
- Notes: Grounded in the OS app design (`2026-07-12-os-app-design.md`): tile 07, status bar mirrors the agent's closing sentence, shared scheduler slot, Override interplay, rule baked into the prompt. Script ladder now: Chat box → ReAct → Tools → Memory → Skills → Process → OS.
|
||||
|
||||
## 2026-07-14 — maintenance (authorized raw edit, OS reframing)
|
||||
- Intent: maintenance
|
||||
- Input: user correction — the webinar's core idea is "make tools for yourself," not "become a product."
|
||||
- Pages changed: `raw/sources/Webinar script.md` — Process→OS hook now ends "…and become a tool? A small one. Made for exactly one person."; OS landing gained the intro callback (weekends burned on internal tools → this one took an evening, asked-for not written) and "It dissolved — into the operating system. Into little tools you make for yourself."; closing arc adds "You don't buy it. You build it — one small tool at a time."
|
||||
- Notes: The OS section now closes the loop with the Intro's internal-tools passion. No wiki pages changed.
|
||||
|
||||
## 2026-07-14 — ingest (batch, 2 sources: Nina + Yulia interviews)
|
||||
- Intent: ingest
|
||||
- Input: `raw/sources/Nina interview.md`, `raw/sources/Yulia interview.md` (both are conclusions docs auto-generated by Eugene's record→diarize→transcribe→summarize tool).
|
||||
- Pages created — sources (2): [[2026-07-14-nina-interview]], [[2026-07-14-yulia-interview]].
|
||||
- Pages created — entities (3): [[nina]] (HR recruiter, Virtido), [[yulia]] (HR lead; name/affiliation tentative, inferred from filename + Nina reference), [[inspectron]] (Eugene's employer).
|
||||
- Pages created — concepts (2): [[levels-of-ai-usage]] (chatbot → memory → Claude Code → CLAUDE.md → skills → KB → RAG; non-programmer ceiling = CLAUDE.md + skills), [[solve-first-then-skillify]] (solve once, then freeze into a skill; ~3-message and >5-tool-call heuristics).
|
||||
- Pages updated: [[eugene]] (identity evidence strengthened — webinar author/presenter, Inspectron, $200 max plan, tool builder; still tentative), [[virtido]] (HR team = webinar audience, pain points, tooling), [[skills-as-memory]] (handoff/de-risking payoff, ~3-message heuristic, method link), [[connections-as-moat]] (Eugene independently converges: "the human's role is just to be human"), [[overview]] (6 sources, demand-side bullet, agree/diverge, navigation, open questions), `index.md`.
|
||||
- Notes: Strong convergence — Eugene ↔ Sebastian/Allie on human-connection residual despite their networking-tactics disagreement; Eugene's ~3-message heuristic ↔ Konstantin's >5-tool-call heuristic. New cross-interview finding: adoption blocked by friction, not resistance. Tentative flags: Yulia's name/affiliation; Eugene's price-rise prediction; Inspectron employment-vs-contracting. Skills-IP-vs-work-product dispute (Eugene vs Sebastian) recorded, unresolved.
|
||||
- Next: ingest "Ideas for webinar" / "Webinar Plan" / "Webinar script" to connect corpus → deliverable; interview Larysa/Larisa (PM use cases, twice flagged); consider a comparison page "personal vs employer ownership of skills".
|
||||
|
||||
## 2026-07-14 — query (network from a standing start)
|
||||
- Intent: query
|
||||
- Input: "how does an individual actually build a network from a standing start?" + "go" on the recommended plan (tentative protocol + Sebastian follow-up instrument).
|
||||
- Pages created: [[network-from-a-standing-start]] (concept, Status: tentative — 5-step protocol: recurring venues → cadence → lead with humanness → engineer second meetings → track second meetings/let referrals work; contested anti-tactics list; webinar flagged as live case study), [[2026-07-14-network-from-standing-start]] (query — 10-question Sebastian round-2 interview instrument in 3 blocks: bootstrap biography / mechanics / falsification of "Big zero").
|
||||
- Pages updated: [[connections-as-moat]] (open question → protocol + validation plan), [[overview]] (vault-level open question annotated), `index.md` (Concepts + Queries sections).
|
||||
- Notes: Corpus cannot answer the question directly — protocol is inferred from Sebastian's principles, Allie's prediction, and Eugene's convergent thesis; every claim marked tentative/contested. Key falsification target: whether Sebastian ever had a true standing start (prior-job network as seed). Deep-research complement (weak ties, mere exposure, from-zero playbooks, scoped to test "Big zero") described but not run.
|
||||
- Next: run the round-2 Sebastian interview and ingest it; decide on the deep-research run; track webinar → paid-HR-build chain as case-study evidence.
|
||||
|
||||
## 2026-07-16 — query → comparison
|
||||
- Intent: query
|
||||
- Input: "Compare Theo's, Konstantin's ('Sonstantine') and Allie's approaches — what they have in common, what they have different?"
|
||||
- Pages created: [[theo-konstantin-allie]] (first `wiki/comparisons/` page — three-lens side-by-side: at-a-glance table, 6 shared points, differences by altitude/framing/code/learning/register, complementary tensions).
|
||||
- Pages updated: [[theo-browne]], [[konstantin]], [[allie-miller]] (added inbound "Comparison:" links to avoid orphan); `index.md` (Comparisons section — first entry).
|
||||
- Notes: Synthesized from the 3 source summaries + entity pages + [[skills-as-memory]]. Common ground: bottleneck moved model→human system; markdown/skills as the atomic unit; infrastructure compounds; system-ready to absorb new models; context as scarce resource; shared [[claude-code]]. Differences framed as *altitude* (Theo strategy/psychology · Konstantin engineering · Allie individual-productivity), not direction — corpus disagreements lie elsewhere. Recorded the throwaway-code (Theo) vs persist-in-git (Konstantin) tension as complementary (artifact vs capability). No new contradictions. Saved as a comparison rather than a query page since the request was explicitly a side-by-side.
|
||||
- Next: reusable starter template (foundation docs / good SKILL.md) still unresolved across all three — webinar-relevant; consider whether Konstantin's meta-loop (wipe-and-restart) tensions with "persist everything".
|
||||
|
||||
## 2026-07-16 — maintenance (table fix)
|
||||
- Intent: maintenance
|
||||
- Input: user report — the table in [[ai-agent-evolution]] "looks broken".
|
||||
- Pages changed: [[ai-agent-evolution]] — repaired the "Agent architecture & tooling (Konstantin)" table; escaped the `|` inside aliased wiki links (`[[harness\|harnesses]]`, `[[skills-as-memory\|skills]]`, `[[agentic-loops\|agent loops]]`) so Obsidian no longer reads them as column separators, and removed the two phantom trailing columns the unescaped pipes had forced into the header/separator. Now a clean 3-column table (Period / Milestone / Significance).
|
||||
- Notes: Content unchanged — formatting-only fix. The Theo Browne table was already valid. No `index.md` change (no catalog/structural change). Root cause: piped `[[page|alias]]` links inside GFM/Obsidian table cells require the pipe escaped as `\|`.
|
||||
|
||||
## 2026-07-21 — ingest (Larysa interview)
|
||||
- Intent: ingest
|
||||
- Input: "ingest Larysa interview.md" → `raw/sources/Larysa interview.md` (auto-generated interview conclusions doc; Eugene × Larysa, technical BA/PM and ex-mobile dev).
|
||||
- Pages created: [[2026-07-21-larysa-interview]] (source), [[larysa]] (entity), [[integration-dead-ends]] (concept — agent begins work against connectors gated by account tier / paid seat / missing API; corpus offers no fix, only up-front verification), [[leave-less-room-for-imagination]] (concept — under-specified prompts drift and the collateral damage is *invisible*; skills as the constraint; includes the 4.7-over-4.8 model-choice corollary).
|
||||
- Pages updated: [[skills-as-memory]] (new "negative case" section — built-in memory as anti-feature, the demand-side reason skills exist; contradiction logged vs Allie), [[harness]] (consolidation-over-tool-hopping section + "before and after" claim marked self-reported), [[code-as-throwaway]] (auth/payments trust carve-out; "safe from 4.6 on"), [[levels-of-ai-usage]] (Larysa as proof the rungs are skippable — technically advanced, architecturally stuck), [[claude-code]] (practitioner-limits section: memory, connectors, 4.6/4.7/4.8, emulator), [[solve-first-then-skillify]], [[personal-ai-operating-system]] (cross-ref to Eugene's convergent OS framing), [[eugene]], [[yulia]] (Larisa open question partially resolved), [[virtido]] (audience extends beyond HR; ClickUp/Figma/Teams/Slack), [[overview]] (6→7 sources, demand-side paragraph, two new divergences, two new vault-level open questions), `index.md`.
|
||||
- Notes: Closes the "Larysa/Larisa not yet interviewed — PM use cases missing" gap flagged in both HR interviews. Key reframe for the webinar: this source moves the diagnosis from *friction* (Nina/Yulia: people would adopt if it were simple) to *structural walls* for users already past friction — memory, entitlements, drift. Two genuine corpus contradictions recorded rather than smoothed: memory-as-anti-feature (Eugene) vs Allie's untroubled use of persistent context docs, and tight-spec vs [[think-wider-not-bigger]]. Also corrected `index.md`: `HR Contacts.md` was listed as not-yet-ingested but does not exist in `raw/sources/` — removed from the list.
|
||||
- Next: remaining un-ingested raw are the three webinar-deliverable docs (`Ideas for webinar.md`, `Webinar Plan - From Chat Box to Your Own OS.md`, `Webinar script.md`) — ingesting them would connect the corpus to the actual deliverable and settle whether the script keeps the [[levels-of-ai-usage]] rung order. Candidate query: does the skills rung actually answer Larysa's memory complaint, or is hers a cross-project problem skills don't solve? A first lint pass is also overdue (no lint reports exist; 7 sources, 17 concepts).
|
||||
|
||||
## 2026-07-22 — query (webinar theses)
|
||||
- Intent: query
|
||||
- Input: "What theses can I suggest for the webinar ('from chatbox to your own agentic operating system') based on what you already have?"
|
||||
- Pages changed: created [[2026-07-22-webinar-theses]]; updated `index.md` (Queries section).
|
||||
- Notes: 14 candidate theses synthesized from [[overview]], the 7 source summaries, and direct reads of the three raw webinar-deliverable docs (Plan, script, Ideas — still raw-only, cited as raw per policy). Grouped: spine (harness-not-model, app-you-open→OS, skills-as-memory, context scarcity, build-not-buy) / stakes (cost→zero, irreversible gap, connections rise) / obstacles (friction-not-resistance, structural walls, less-room-for-imagination) / method (solve-first-then-skillify, research-vs-judgment, walk-in-a-week) / honest tensions (3 recorded contradictions offered as Q&A ammo). Recommended 7-thesis subset for the 30-min format noted in the query page. No concept/entity pages changed.
|
||||
- Next: ingest the three deliverable docs so theses can cite wiki sources instead of raw; decide whether the "obstacles" theses earn a station on the spine.
|
||||
|
||||
## 2026-07-22 — ingest (ИИ глупый! short)
|
||||
- Intent: ingest
|
||||
- Input: "ingest \"ИИ глупый!\"" → `raw/sources/ИИ глупый!.md` (conclusions doc for a 1:28 Russian YouTube Short, author unknown; file was added mid-session after the first lookup found nothing).
|
||||
- Pages created: [[2026-07-22-ai-is-stupid]] (source).
|
||||
- Pages updated: [[harness]] (business-facing "engineering wrapper" definition + model+context+harness formula, flagged as webinar language), [[context-as-scarce-resource]] (supply-side facet: "intelligence without context loses to context without intelligence", Nobel-vs-employee analogy; RAG-vs-skills tension logged under Contradictions), [[overview]] (7→8 sources, convergence one-liner, navigation), `index.md` (Sources entry; `my theses.md` added to the not-yet-ingested list).
|
||||
- Notes: No new concepts — the short *restates* the vault's machine-side spine for a business audience, which makes it webinar-quotable rather than novel. One tension recorded, not smoothed: it recommends RAG/long-term memory as context mechanisms where Konstantin argues skills beat RAG (possibly audience-driven — business data vs procedures). Authorship unknown and marked tentative; its framing matches the corpus closely enough that a connection to someone already in the corpus is worth checking. All ×10…×1000 gain claims are rhetorical, not measured.
|
||||
- Next: `my theses.md` is new in raw and un-ingested (six webinar thesis one-liners) — small, high-relevance ingest candidate; the three webinar-deliverable docs remain pending; first lint pass still overdue (8 sources, 17 concepts, 0 lint reports).
|
||||
|
||||
## 2026-07-24 — ingest (You're reading way too much code)
|
||||
- Intent: ingest
|
||||
- Input: "ingest \"You're reading way too much code\"" → `raw/sources/You're reading way too much code.md` (conclusions doc for Theo Browne's 24:11 video; his second source in the vault).
|
||||
- Pages created: [[2026-07-24-youre-reading-way-too-much-code]] (source), [[make-more-cheap-code]] (concept — ship/no-ship line, four tiers of code A–D, 100–10,000:1 slop-to-ship verification ratio, always-another-layer, dumb-model agents as API usability testers, reading-costs-attention economics).
|
||||
- Pages updated: [[code-as-throwaway]] (discipline section; evidence; its "what is the durable artifact" open question partially answered — the verification harness is now a named first-class output), [[theo-browne]] (second talk, recurring author-move noted, self-reported ratios flagged tentative), [[leave-less-room-for-imagination]] (new logged tension: Theo/Dax agent-diff-summaries vs Eugene's invisible-drift claim), [[2026-07-14-everything-we-knew-about-software-has-changed]] (reciprocal related-source link), [[overview]] (8→9 sources; verifying-half of spine given its method; new divergence line; 17→18 concepts), `index.md` (Sources, People, Concepts entries).
|
||||
- Notes: The source is a *defense with discipline*, not a reversal — Theo explicitly rejects shipping unreviewed slop, which pre-empts the obvious objection to [[code-as-throwaway]]. Strong webinar relevance: "attention, not generation, is the bottleneck" is the engineer-side twin of [[context-as-scarce-resource]], and the tier framework gives audiences a non-binary answer to "can I trust AI code?". One genuine tension recorded rather than smoothed (summaries-hide-drift). Shao's 80%-into-harnesses ratio and all of Theo's daily-line counts are self-reported/uncited — marked tentative. Open framework gap flagged: skills/CLAUDE.md files don't fit the A–D spectrum.
|
||||
- Next: candidate query — what is the non-engineer's analog of throwaway verification code (HR/BA audience)? `my theses.md` and the three webinar-deliverable docs remain un-ingested; first lint pass still overdue (9 sources, 18 concepts, 0 lint reports).
|
||||
|
||||
## 2026-07-24 — query (non-engineer throwaway verification)
|
||||
- Intent: query
|
||||
- Input: "query: what is the non-engineer's analog of throwaway verification code?" (the candidate query flagged in the previous ingest).
|
||||
- Pages created: [[2026-07-24-non-engineer-throwaway-verification]] (query — answer: disposable AI work that attacks/misreads/simulates the deliverable before a human sees it; one-to-one mapping table from Theo's engineer patterns to HR/BA use cases; "checker skills" as the second species of skill; tier-D-stays-human caveat since non-engineer verification bottoms out in judgment, not tests).
|
||||
- Pages updated: [[make-more-cheap-code]] (next-question marked answered, link added), [[leave-less-room-for-imagination]] (new next-question: drift harnessed as a sandboxed ambiguity diagnostic — synthesis, tentative), `index.md` (Queries section).
|
||||
- Notes: Pure synthesis, no new source — every mapped pattern is grounded in corpus use cases (Nina/Yulia job descriptions, candidate KB, sourcing; Larysa spec ambiguity; Allie's anti-AI-language checker-skill precedent). Key reframes with durable value: (1) the fresh-agent misread test inverts [[leave-less-room-for-imagination]] — drift becomes a diagnostic when sandboxed; (2) [[solve-first-then-skillify]] populates skills in two species, producers and checkers. Flagged honestly: the whole mapping is argument-by-analogy with no measured claim; Nina's transcript-beats-summary finding is a standing counterweight to summary-based review.
|
||||
- Next: decide whether "checker skills" earns a slide on the webinar's skills rung; the webinar-deliverable docs (`Ideas`, `Plan`, `script`, `my theses.md`) remain un-ingested; first lint pass still overdue (9 sources, 18 concepts, 2026-07-24 now has 1 query, 0 lint reports).
|
||||
|
||||
## 2026-07-28 — sync (script coverage, initial)
|
||||
- Intent: sync script coverage
|
||||
- Input: first run of Workflow D, establishing `wiki/script-coverage.md`.
|
||||
- Pages created: [[script-coverage]] (coverage) — 19 rows, one per concept page.
|
||||
- Pages updated: `CLAUDE.md` (folder convention, `#coverage` tag row, Workflow D, new intent), `index.md` (new Coverage section; corrected the not-yet-ingested list — `Ideas for webinar.md` and `my theses.md` were listed under `raw/sources/` but live in `raw/notes/`, and `Agentic Engineering, explained by a 10x developer.md` was missing entirely).
|
||||
- Notes: Initial assessment is 5 covered, 4 partial, 10 absent. Eight of the ten absent are human-side or strategy-side per the grouping in index.md; the other two — [[integration-dead-ends]] and [[leave-less-room-for-imagination]] — are machine-side, absent because the script demos the happy path and never reaches connector gating or spec ambiguity. The `ReAct` station carries no wiki concept. No concept pages were edited.
|
||||
- Next: decide whether the human-side cluster earns a station or is a deliberate cut; decide separately whether the two absent machine-side failure modes belong in the demo; pin the rows that are decided so future syncs leave them alone.
|
||||
|
||||
@@ -1,45 +1,45 @@
|
||||
# Script coverage
|
||||
|
||||
#coverage
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Script:** `raw/sources/Webinar script.md`
|
||||
- **Last synced:** 2026-07-28
|
||||
- **Stations:** Chat box · ReAct · Tools · Memory · Skills · Process · OS
|
||||
|
||||
## Coverage
|
||||
|
||||
| Concept | Status | Station | Pinned |
|
||||
|---|---|---|---|
|
||||
| [[harness]] | covered | Tools | |
|
||||
| [[evolution-of-agent-tooling]] | covered | Tools | |
|
||||
| [[skills-as-memory]] | covered | Skills | |
|
||||
| [[solve-first-then-skillify]] | covered | Skills | |
|
||||
| [[personal-ai-operating-system]] | covered | OS | |
|
||||
| [[context-as-scarce-resource]] | partial | Memory | |
|
||||
| [[agentic-loops]] | partial | Process | |
|
||||
| [[code-as-throwaway]] | partial | OS | |
|
||||
| [[levels-of-ai-usage]] | partial | all | |
|
||||
| [[integration-dead-ends]] | absent | — | |
|
||||
| [[leave-less-room-for-imagination]] | absent | — | |
|
||||
| [[product-ownership]] | absent | — | |
|
||||
| [[connections-as-moat]] | absent | — | |
|
||||
| [[network-from-a-standing-start]] | absent | — | |
|
||||
| [[seniority-and-the-junior-squeeze]] | absent | — | |
|
||||
| [[decoupling-identity-from-profession]] | absent | — | |
|
||||
| [[think-wider-not-bigger]] | absent | — | |
|
||||
| [[make-more-cheap-code]] | absent | — | |
|
||||
| [[enterprise-ai-reality]] | absent | — | |
|
||||
|
||||
## Notes
|
||||
|
||||
- Eight of the ten absent concepts are human-side or strategy-side, per the grouping in `index.md`. The script's spine is machine-side and it never reaches that material.
|
||||
- The remaining two absent concepts are machine-side: [[integration-dead-ends]] and [[leave-less-room-for-imagination]]. The script demonstrates the happy path, so it never reaches connector gating or spec ambiguity — the two ways the machine side fails in practice.
|
||||
- The `ReAct` station carries no wiki concept at all.
|
||||
- Set `Pinned` to `yes` on any row whose status is a deliberate decision. Sync will not touch it.
|
||||
|
||||
## Related Pages
|
||||
|
||||
- [[overview]]
|
||||
- `raw/sources/Webinar script.md`
|
||||
# Script coverage
|
||||
|
||||
#coverage
|
||||
|
||||
## Metadata
|
||||
|
||||
- **Script:** `raw/sources/Webinar script.md`
|
||||
- **Last synced:** 2026-07-28
|
||||
- **Stations:** Chat box · ReAct · Tools · Memory · Skills · Process · OS
|
||||
|
||||
## Coverage
|
||||
|
||||
| Concept | Status | Station | Pinned |
|
||||
|---|---|---|---|
|
||||
| [[harness]] | covered | Tools | |
|
||||
| [[evolution-of-agent-tooling]] | covered | Tools | |
|
||||
| [[skills-as-memory]] | covered | Skills | |
|
||||
| [[solve-first-then-skillify]] | covered | Skills | |
|
||||
| [[personal-ai-operating-system]] | covered | OS | |
|
||||
| [[context-as-scarce-resource]] | partial | Memory | |
|
||||
| [[agentic-loops]] | partial | Process | |
|
||||
| [[code-as-throwaway]] | partial | OS | |
|
||||
| [[levels-of-ai-usage]] | partial | all | |
|
||||
| [[integration-dead-ends]] | absent | — | |
|
||||
| [[leave-less-room-for-imagination]] | absent | — | |
|
||||
| [[product-ownership]] | absent | — | |
|
||||
| [[connections-as-moat]] | absent | — | |
|
||||
| [[network-from-a-standing-start]] | absent | — | |
|
||||
| [[seniority-and-the-junior-squeeze]] | absent | — | |
|
||||
| [[decoupling-identity-from-profession]] | absent | — | |
|
||||
| [[think-wider-not-bigger]] | absent | — | |
|
||||
| [[make-more-cheap-code]] | absent | — | |
|
||||
| [[enterprise-ai-reality]] | absent | — | |
|
||||
|
||||
## Notes
|
||||
|
||||
- Eight of the ten absent concepts are human-side or strategy-side, per the grouping in `index.md`. The script's spine is machine-side and it never reaches that material.
|
||||
- The remaining two absent concepts are machine-side: [[integration-dead-ends]] and [[leave-less-room-for-imagination]]. The script demonstrates the happy path, so it never reaches connector gating or spec ambiguity — the two ways the machine side fails in practice.
|
||||
- The `ReAct` station carries no wiki concept at all.
|
||||
- Set `Pinned` to `yes` on any row whose status is a deliberate decision. Sync will not touch it.
|
||||
|
||||
## Related Pages
|
||||
|
||||
- [[overview]]
|
||||
- `raw/sources/Webinar script.md`
|
||||
|
||||
Reference in New Issue
Block a user