linersh 1.0.2 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +43 -5
- package/bin/liner.js +99 -17
- package/cli-update-docs/README.md +23 -3
- package/cli-update-docs/SKILL.md +16 -3
- package/cli-update-docs/curator-notes.md +11 -10
- package/cli-update-docs/quality-check-tests.md +1 -11
- package/cli-update-docs/source-finding-tactics.md +0 -12
- package/cli-update-docs/source-quality-hierarchy.md +0 -4
- package/cli-update-docs/synthesis-guidance.md +6 -2
- package/dist/agents/artifact-validation.js +69 -5
- package/dist/agents/artifact-validation.js.map +1 -1
- package/dist/agents/candidate-longlist.js +21 -5
- package/dist/agents/candidate-longlist.js.map +1 -1
- package/dist/agents/detect.js +17 -3
- package/dist/agents/detect.js.map +1 -1
- package/dist/agents/headless-runner.js +218 -13
- package/dist/agents/headless-runner.js.map +1 -1
- package/dist/agents/jtbd-clarify.js +26 -2
- package/dist/agents/jtbd-clarify.js.map +1 -1
- package/dist/agents/models.js +66 -14
- package/dist/agents/models.js.map +1 -1
- package/dist/agents/prompts.js +37 -1
- package/dist/agents/prompts.js.map +1 -1
- package/dist/agents/runner.js +153 -39
- package/dist/agents/runner.js.map +1 -1
- package/dist/config.js +156 -15
- package/dist/config.js.map +1 -1
- package/dist/phases.js +13 -0
- package/dist/phases.js.map +1 -1
- package/dist/progress.js +2 -0
- package/dist/progress.js.map +1 -1
- package/maintenance-skill/SKILL.md +18 -0
- package/maintenance-skill/agents/openai.yaml +4 -0
- package/package.json +16 -10
package/README.md
CHANGED
|
@@ -26,12 +26,37 @@ liner
|
|
|
26
26
|
```
|
|
27
27
|
|
|
28
28
|
With no arguments, `liner` launches the Go TUI. CLI subcommands such as
|
|
29
|
-
`liner compile`, `liner share`, `liner import`, `liner
|
|
30
|
-
`liner
|
|
29
|
+
`liner compile`, `liner share`, `liner import`, `liner project`,
|
|
30
|
+
`liner sources`, `liner adapters`, `liner status`, and `liner setup-js` pass
|
|
31
|
+
through to the Python core. If you are using one-shot
|
|
31
32
|
`npx` instead of a global install, pass subcommands through the package:
|
|
32
33
|
`npx --yes linersh@latest setup-js` or
|
|
33
34
|
`npx --yes linersh@latest uninstall --yes`.
|
|
34
35
|
|
|
36
|
+
## Safe Project Maintenance
|
|
37
|
+
|
|
38
|
+
The installed CLI is the authority for supported Project and Source changes.
|
|
39
|
+
Inspection and planning are write-free; apply revalidates one exact versioned
|
|
40
|
+
Change Set and writes a durable, redacted Change Receipt.
|
|
41
|
+
|
|
42
|
+
```sh
|
|
43
|
+
liner project guidance <project> --format markdown
|
|
44
|
+
liner project inspect <project> --json
|
|
45
|
+
liner sources add <project> --type web --url <url> --note <note>
|
|
46
|
+
liner project rename <project> --name <name>
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The Go TUI's `Maintain project` command uses the same contract. Optional Codex
|
|
50
|
+
and Claude Maintenance Adapters are explicit CLI-delegating installations:
|
|
51
|
+
|
|
52
|
+
```sh
|
|
53
|
+
liner adapters inspect codex
|
|
54
|
+
liner adapters install codex --yes
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
The Maintenance Adapter is not the Project Skill, and a `type: skill` Source is
|
|
58
|
+
inert reference material rather than installed instructions.
|
|
59
|
+
|
|
35
60
|
## Try It Cleanly
|
|
36
61
|
|
|
37
62
|
For a regular-user smoke test without touching your real Liner workspace:
|
|
@@ -50,12 +75,22 @@ rm -rf "$tmp"
|
|
|
50
75
|
```
|
|
51
76
|
|
|
52
77
|
The second command opens the Go TUI. Create a test Liner Project, build the
|
|
53
|
-
corpus with your configured
|
|
54
|
-
Operating Layer. Because `HOME`, the npm cache, and `LINER_DIR`
|
|
55
|
-
`$tmp`, cleanup is just `rm -rf "$tmp"`.
|
|
78
|
+
corpus with your configured OpenAI (Codex CLI) or Claude (Claude Code) runner,
|
|
79
|
+
then run Create Operating Layer. Because `HOME`, the npm cache, and `LINER_DIR`
|
|
80
|
+
all point inside `$tmp`, cleanup is just `rm -rf "$tmp"`.
|
|
56
81
|
|
|
57
82
|
## Run Locally
|
|
58
83
|
|
|
84
|
+
For normal repository testing, use the isolated launch so Projects and Settings
|
|
85
|
+
cannot write to the production Liner library or profile:
|
|
86
|
+
|
|
87
|
+
```sh
|
|
88
|
+
npm --prefix packages/tui run dev:isolated
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
See [../../docs/development.md](../../docs/development.md) for explicit
|
|
92
|
+
authenticated provider-home options and the offline runner-preferences smoke.
|
|
93
|
+
|
|
59
94
|
From the repo root:
|
|
60
95
|
|
|
61
96
|
```sh
|
|
@@ -98,6 +133,9 @@ Notes:
|
|
|
98
133
|
- Release packaging is verified with `npm run acceptance:go -- release-smoke`,
|
|
99
134
|
which packs a local platform package plus the main `linersh` package and
|
|
100
135
|
installs both into a clean consumer project.
|
|
136
|
+
- `npm run release:check` is offline and verifies repository consistency.
|
|
137
|
+
`npm run release:check:publish` additionally refuses to publish the main
|
|
138
|
+
package when its canonical version already exists on npm.
|
|
101
139
|
|
|
102
140
|
## Useful Environment Variables
|
|
103
141
|
|
package/bin/liner.js
CHANGED
|
@@ -19,6 +19,75 @@ const here = dirname(fileURLToPath(import.meta.url));
|
|
|
19
19
|
const packageRoot = join(here, "..");
|
|
20
20
|
const argv = process.argv.slice(2);
|
|
21
21
|
|
|
22
|
+
const COMMAND_GROUPS = [
|
|
23
|
+
{
|
|
24
|
+
title: "Common workflow commands:",
|
|
25
|
+
commands: [
|
|
26
|
+
{ name: "init", description: "Create a Liner Project", owner: "core" },
|
|
27
|
+
{ name: "compile", description: "Build MIXTAPE.md from a Liner Project", owner: "core" },
|
|
28
|
+
{ name: "share", description: "Create a shareable .mixtape file", owner: "core" },
|
|
29
|
+
{
|
|
30
|
+
name: "import",
|
|
31
|
+
description: "Import a .mixtape file as a Liner Project",
|
|
32
|
+
owner: "core",
|
|
33
|
+
},
|
|
34
|
+
{ name: "list", description: "List Liner Projects", owner: "core" },
|
|
35
|
+
{ name: "status", description: "Show Liner Project status", owner: "core" },
|
|
36
|
+
{ name: "setup-js", description: "Set up JavaScript rendering support", owner: "core" },
|
|
37
|
+
{ name: "uninstall", description: "Remove local Liner state and caches", owner: "launcher" },
|
|
38
|
+
{
|
|
39
|
+
name: "--version",
|
|
40
|
+
description: "Show installed launcher and core versions (-v)",
|
|
41
|
+
owner: "launcher",
|
|
42
|
+
},
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
title: "Advanced maintenance commands:",
|
|
47
|
+
commands: [
|
|
48
|
+
{
|
|
49
|
+
name: "replay",
|
|
50
|
+
description: "Clone project inputs with lineage for later comparison",
|
|
51
|
+
owner: "core",
|
|
52
|
+
},
|
|
53
|
+
{ name: "clone", description: "Fetch or copy a project recipe", owner: "core" },
|
|
54
|
+
{
|
|
55
|
+
name: "skills",
|
|
56
|
+
description: "Find installed skills that can be used as Sources",
|
|
57
|
+
owner: "core",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: "sources",
|
|
61
|
+
description: "Plan and apply Source maintenance",
|
|
62
|
+
owner: "core",
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: "adapters",
|
|
66
|
+
description: "Manage optional Maintenance Adapters",
|
|
67
|
+
owner: "core",
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: "project",
|
|
71
|
+
description: "Inspect, plan, and apply Project maintenance",
|
|
72
|
+
owner: "core",
|
|
73
|
+
},
|
|
74
|
+
{ name: "cache", description: "Inspect or clear the Source cache", owner: "core" },
|
|
75
|
+
{ name: "manifest", description: "Build or inspect a Source manifest", owner: "core" },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
];
|
|
79
|
+
|
|
80
|
+
const CLI_COMMANDS = new Set(
|
|
81
|
+
COMMAND_GROUPS.flatMap((group) =>
|
|
82
|
+
group.commands.filter((command) => command.owner === "core").map((command) => command.name),
|
|
83
|
+
),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
if (argv.length === 1 && (argv[0] === "--help" || argv[0] === "-h")) {
|
|
87
|
+
printHelp();
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
22
91
|
// `liner --version` used to forward straight to the Python core, so it
|
|
23
92
|
// reported the core version (e.g. 0.5.0) regardless of which TUI package was
|
|
24
93
|
// installed — confusing when verifying an npm publish. Report the npm/TUI
|
|
@@ -34,25 +103,10 @@ if (argv[0] === "uninstall") {
|
|
|
34
103
|
process.exit(code);
|
|
35
104
|
}
|
|
36
105
|
|
|
37
|
-
const CLI_COMMANDS = new Set([
|
|
38
|
-
"init",
|
|
39
|
-
"replay",
|
|
40
|
-
"compile",
|
|
41
|
-
"share",
|
|
42
|
-
"import",
|
|
43
|
-
"clone",
|
|
44
|
-
"setup-js",
|
|
45
|
-
"list",
|
|
46
|
-
"skills",
|
|
47
|
-
"cache",
|
|
48
|
-
"manifest",
|
|
49
|
-
"status",
|
|
50
|
-
]);
|
|
51
|
-
|
|
52
106
|
function wantsCli(args) {
|
|
53
107
|
if (args.length === 0) return false;
|
|
54
108
|
const first = args[0];
|
|
55
|
-
return first === "--
|
|
109
|
+
return first === "--version" || CLI_COMMANDS.has(first);
|
|
56
110
|
}
|
|
57
111
|
|
|
58
112
|
if (wantsCli(argv)) {
|
|
@@ -345,6 +399,33 @@ function readTuiVersion() {
|
|
|
345
399
|
}
|
|
346
400
|
}
|
|
347
401
|
|
|
402
|
+
function printHelp() {
|
|
403
|
+
const lines = [
|
|
404
|
+
"Liner — build and use source-grounded Liner Projects.",
|
|
405
|
+
"",
|
|
406
|
+
"Usage:",
|
|
407
|
+
" liner Open the Go TUI",
|
|
408
|
+
" liner <command> [options] Run a command",
|
|
409
|
+
"",
|
|
410
|
+
"liner with no arguments opens the Go TUI.",
|
|
411
|
+
"Run `liner <command> --help` for detailed command help.",
|
|
412
|
+
"",
|
|
413
|
+
];
|
|
414
|
+
for (const group of COMMAND_GROUPS) {
|
|
415
|
+
lines.push(group.title);
|
|
416
|
+
for (const command of group.commands) {
|
|
417
|
+
lines.push(` ${command.name.padEnd(10)} ${command.description}`);
|
|
418
|
+
}
|
|
419
|
+
lines.push("");
|
|
420
|
+
}
|
|
421
|
+
lines.push(
|
|
422
|
+
"Options:",
|
|
423
|
+
" -h, --help Show this help",
|
|
424
|
+
" -v, --version Show version information",
|
|
425
|
+
);
|
|
426
|
+
console.log(lines.join("\n"));
|
|
427
|
+
}
|
|
428
|
+
|
|
348
429
|
// Like resolveCliBinary() but non-fatal: returns null instead of exiting when
|
|
349
430
|
// no core binary is found, so `--version` still prints the TUI version on a
|
|
350
431
|
// host where the bundled core is missing (e.g. Windows pre-unblock).
|
|
@@ -355,7 +436,8 @@ function tryResolveCliCommand() {
|
|
|
355
436
|
}
|
|
356
437
|
|
|
357
438
|
function tryResolveHeadlessRunnerScript() {
|
|
358
|
-
|
|
439
|
+
const candidate = join(packageRoot, "dist", "agents", "headless-runner.js");
|
|
440
|
+
return existsSync(candidate) ? candidate : null;
|
|
359
441
|
}
|
|
360
442
|
|
|
361
443
|
function printVersion() {
|
|
@@ -2,7 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
This is the Liner methodology made executable by Claude or Codex. The bundle implements CURATION.md v2.0 as instructions to a running AI, drives the mixtape lifecycle from a task description to a project folder ready for `liner compile`, and supports both quick mode (the AI does most of the work, with lightweight gate review) and methodology mode (the curator engages substantively at every phase).
|
|
4
4
|
|
|
5
|
-
It is one of Liner's surfaces, alongside the CLI
|
|
5
|
+
It is one of Liner's authoring surfaces, alongside the CLI and TUI. The skill is
|
|
6
|
+
the surface for Claude-Code-native and TUI-subprocess curation. Methodology-mode
|
|
7
|
+
curators can also use it directly when working in a Claude Code session. It is
|
|
8
|
+
not the Project Skill or the optional Maintenance Adapter.
|
|
6
9
|
|
|
7
10
|
## Bundle contents
|
|
8
11
|
|
|
@@ -80,7 +83,22 @@ The bundle is functional and ships inside the npm TUI package so agent-backed ph
|
|
|
80
83
|
|
|
81
84
|
The bundle still benefits from more worked examples in the companion files, but it is no longer blocked by the old "second pass before any shipping" constraint. Current product risk lives more in curation quality and fetcher edge cases than in basic skill availability.
|
|
82
85
|
|
|
83
|
-
|
|
86
|
+
In the local `1.1.0` release candidate, compilation is the Corpus Ready
|
|
87
|
+
milestone and Create Operating Layer is the Project Complete milestone. A
|
|
88
|
+
project can be usable when `MIXTAPE.md` is written but some Sources are missing
|
|
89
|
+
or soft-failed after review. The TUI opens the existing compile result and
|
|
90
|
+
requires an explicit retry or rerun. Phase 1 must produce a Capability Brief and
|
|
91
|
+
Required source roles before discovery can proceed.
|
|
92
|
+
|
|
93
|
+
## Three Skill Surfaces
|
|
94
|
+
|
|
95
|
+
- The **curating-mixtapes skill** authors the initial corpus recipe, synthesis,
|
|
96
|
+
and working notes. It never performs post-creation maintenance.
|
|
97
|
+
- The root **Project Skill** is created by the Operating Layer and teaches future
|
|
98
|
+
sessions how to use one completed Project.
|
|
99
|
+
- The optional **Maintenance Adapter** is installed explicitly for Codex or
|
|
100
|
+
Claude and delegates supported changes to the installed CLI's current
|
|
101
|
+
guidance. A `type: skill` Source remains inert evidence and is not installed.
|
|
84
102
|
|
|
85
103
|
## Versioning
|
|
86
104
|
|
|
@@ -98,7 +116,9 @@ The skill is the methodology made executable. It sits alongside Liner's other su
|
|
|
98
116
|
|
|
99
117
|
**CURATION.md** is the methodology described to humans. The skill bundle implements it for an AI executor. The two are paired artifacts that update together when the methodology changes substantively.
|
|
100
118
|
|
|
101
|
-
**The Liner CLI** runs `liner compile` against the project folder this skill
|
|
119
|
+
**The Liner CLI** runs `liner compile` against the project folder this skill
|
|
120
|
+
produces and owns supported post-creation maintenance. The curation skill never
|
|
121
|
+
compiles and never bypasses the Core maintenance contract.
|
|
102
122
|
|
|
103
123
|
**The Liner TUI** invokes this skill internally for agent-backed authoring via the local Claude or Codex CLI. Same methodology, different UX.
|
|
104
124
|
|
package/cli-update-docs/SKILL.md
CHANGED
|
@@ -9,6 +9,11 @@ This skill implements the Liner curation methodology (CURATION.md v2.0). A mixta
|
|
|
9
9
|
|
|
10
10
|
The output of this skill is a project folder ready for `liner compile`. The skill does not compile.
|
|
11
11
|
|
|
12
|
+
This is an initial curation surface, not a maintenance writer. After a Liner
|
|
13
|
+
Project has identity-bearing Project or Source state, supported changes must go
|
|
14
|
+
through the installed CLI's current `liner project guidance` contract. Do not
|
|
15
|
+
use this skill to edit canonical Project files as a maintenance shortcut.
|
|
16
|
+
|
|
12
17
|
**Runtime requirement:** this skill assumes filesystem access. It reads companion files from its own directory at specific phases and writes artifacts to a project folder. Designed for execution inside Claude Code or as a subprocess driven by the Liner TUI. Not designed for pure-chat use.
|
|
13
18
|
|
|
14
19
|
## Terminology — get these right
|
|
@@ -83,6 +88,8 @@ Your job in Phase 1 is to translate that plain-language goal into a Capability B
|
|
|
83
88
|
- source requirements and exclusions,
|
|
84
89
|
- runtime behavior for the future agent, including when it should ask the user clarifying questions.
|
|
85
90
|
|
|
91
|
+
Use these exact level-three headings inside the Capability Brief so the Operating Layer can promote the contract reliably: `### Reusable AI capability`, `### Exact runtime output contract`, `### Internal job-to-be-done`, `### Inferred research lanes`, `### Required source roles`, `### Source exclusions`, and `### Runtime autonomy, abstention, and escalation`.
|
|
92
|
+
|
|
86
93
|
The internal JTBD should be hyper-specific. "SEO" is a topic. "SEO keyword research for a mental-health startup specialized in brain surgery" is a capability narrow enough to research. If the user's goal is still broad, ask targeted questions and descend until the capability is specific enough that a corpus built for it could outperform generic model knowledge.
|
|
87
94
|
|
|
88
95
|
**Capability brief.** A short statement of the concrete capability this mixtape should give a downstream AI agent. This is not a persona or project name. It is the work the corpus must make the agent better at.
|
|
@@ -202,9 +209,12 @@ Order sources within each section by importance (most important first). Order se
|
|
|
202
209
|
- `version: 1`
|
|
203
210
|
- `mode` is `quick` or `methodology`
|
|
204
211
|
- `sources` is non-empty
|
|
205
|
-
- Every source has `type` and `
|
|
206
|
-
- Every `type` is `youtube` or `
|
|
207
|
-
- Every `url`
|
|
212
|
+
- Every source has `type`, `note`, and `section`
|
|
213
|
+
- Every `type` is `youtube`, `web`, `local_file`, or `skill`
|
|
214
|
+
- Every `youtube` or `web` source has a parseable `url`
|
|
215
|
+
- Every `local_file` source has `path` and `citation`
|
|
216
|
+
- Every local or installed `skill` Source has `path`; a remote skill Source has
|
|
217
|
+
a parseable `url`
|
|
208
218
|
|
|
209
219
|
If validation fails, fix and re-check before showing the user.
|
|
210
220
|
|
|
@@ -261,6 +271,9 @@ Tell the user the folder is ready to compile with `liner compile <topic-slug>`.
|
|
|
261
271
|
- **Does not run `liner compile`.** That's the user's call, with the user's tools.
|
|
262
272
|
- **Does not fetch from gated accounts or private systems.** v1 supports public `youtube` and `web` URLs plus curator-supplied `local_file` and `skill` sources. The skill may reference local files the curator supplied, but it must not invent private paths or bypass access controls.
|
|
263
273
|
- **Does not maintain the shared content cache.** That's the CLI's job.
|
|
274
|
+
- **Does not maintain an existing Liner Project.** Use Liner Core directly or
|
|
275
|
+
install the optional Maintenance Adapter, which delegates to
|
|
276
|
+
`liner project guidance`.
|
|
264
277
|
- **Does not publish to the library.** Library contributions happen via PR to the Liner repo, in methodology mode, after passing the empirical test.
|
|
265
278
|
|
|
266
279
|
## Common failure modes
|
|
@@ -72,13 +72,14 @@ In both modes, notes are required. A source without a note doesn't ship.
|
|
|
72
72
|
|
|
73
73
|
## Worked examples
|
|
74
74
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
75
|
+
Good notes:
|
|
76
|
+
|
|
77
|
+
- "Watch first for the operating model: the middle section names the workflow constraint this corpus adopts. Dated on tool names, durable on the interaction principle."
|
|
78
|
+
- "Use as the counterpoint to the default stance. Strong on risks and failure modes; do not treat it as the corpus's main recommendation."
|
|
79
|
+
- "Skim the setup and use the worked example section. It shows the output bar, but the implementation details are platform-specific."
|
|
80
|
+
|
|
81
|
+
Bad notes:
|
|
82
|
+
|
|
83
|
+
- "Useful overview of the topic."
|
|
84
|
+
- "Highly recommended resource."
|
|
85
|
+
- "Good background reading."
|
|
@@ -90,8 +90,6 @@ If yes, keep the better one and cut the other. Volume is not a virtue. Five exce
|
|
|
90
90
|
|
|
91
91
|
Redundancy is different from coverage. Two sources covering the same topic from different angles or with different evidence is coverage, not redundancy. The test is whether the AI would generate meaningfully different output with both vs. with only one. If not, redundant.
|
|
92
92
|
|
|
93
|
-
> TODO: Insert a worked example from the Cowork synthesis where two sources were collapsed because of redundancy. The Van Slyck talk appearing in transcripts 02 and 03 is a known case — same talk uploaded twice. Show how the redundancy was named and resolved.
|
|
94
|
-
|
|
95
93
|
---
|
|
96
94
|
|
|
97
95
|
## Test 2 — The coverage test
|
|
@@ -107,8 +105,6 @@ A mixtape that silently omits a major area is worse than one that says explicitl
|
|
|
107
105
|
|
|
108
106
|
If a section has sources but they're all rated 2 or 3, that's a weak-coverage signal — the section is technically populated but the sources aren't load-bearing. Either find stronger sources or note the weakness.
|
|
109
107
|
|
|
110
|
-
> TODO: Insert a worked example. If the Cowork synthesis had a section that needed reinforcement after first-pass evaluation, show the coverage check that surfaced it and how the gap was addressed.
|
|
111
|
-
|
|
112
108
|
---
|
|
113
109
|
|
|
114
110
|
## Test 3 — The disagreement test
|
|
@@ -123,8 +119,6 @@ If the topic is genuinely uncontested — the W3C HTML spec, for example, isn't
|
|
|
123
119
|
|
|
124
120
|
**The test in action:** identify the strongest claim in the corpus. Search for "[claim] critique" or "[claim] is wrong" or "alternative to [claim]." If you find a credible critique you haven't included, you've found your dissenting source. Add it.
|
|
125
121
|
|
|
126
|
-
> TODO: Insert a worked example from CLI/TUI research. The corpus probably had a contested-question moment — possibly around whether CLIs should follow Unix conventions strictly vs. break them deliberately, or around accessibility being assumed-by-default vs. explicitly designed-for. Surface the actual disagreement and how it was handled.
|
|
127
|
-
|
|
128
122
|
---
|
|
129
123
|
|
|
130
124
|
## Test 4 — The framing-gap test
|
|
@@ -189,8 +183,6 @@ The earlier loose version of this test failed quietly in practice. A real sessio
|
|
|
189
183
|
|
|
190
184
|
If the framing gap is real, accept the cost of going back. Phase 2 is cheap relative to shipping a mixtape with a hole in it.
|
|
191
185
|
|
|
192
|
-
> TODO: Insert the canonical worked example from the Cowork synthesis. OpenClaw's initial 50-source list was anchored in "CLI/TUI implementation" framing and missed "the entire wizard/form-design tradition (Form Design Patterns, NN/g articles, Tidwell, Cooper)." Cowork ran the framing-gap test, named the missing tradition, added 43 net-new sources, and reframed the corpus. This is the textbook framing-gap-test rescue. Pull the specific moment the gap was identified and the specific sources added.
|
|
193
|
-
|
|
194
186
|
---
|
|
195
187
|
|
|
196
188
|
## Test 5 — Source-kind balance
|
|
@@ -407,7 +399,7 @@ Don't paper over failures. The point of running the tests is to find problems wh
|
|
|
407
399
|
- **Disagreement fails:** find one strong dissenting source. Fetch it. Evaluate it. Add it to the keep-list with a note that names its role as counterpoint.
|
|
408
400
|
- **Framing-gap fails:** this is the expensive one. Expand the knowledge map. Return to Phase 2. Find candidates for the new sections. Fetch, evaluate. Come back to Phase 5 with a substantially revised keep-list and re-run all eight tests.
|
|
409
401
|
- **Note-quality fails:** rewrite weak notes in `working/03-evaluation.yaml` so each one carries a use cue, value/bar, and boundary. Do this from existing evidence; do not open a new search loop.
|
|
410
|
-
- **Source-role fit fails / Operating-fit fails:** write `working/05-operating-fit-audit.md` with the missing source role, why it matters, concrete search lanes for an improvement pass, and a short list of
|
|
402
|
+
- **Source-role fit fails / Operating-fit fails:** write `working/05-operating-fit-audit.md` with the missing source role, why it matters, concrete search lanes for an improvement pass, and a short list of user-provided Sources that could fill the gap if public research remains thin.
|
|
411
403
|
|
|
412
404
|
Each backtrack is a sign the methodology is working, not failing. The first four phases produced a corpus that worked from one angle; Phase 5 found the angle that wasn't covered. Better to find it here than in the empirical test (Phase 8) or — worse — silently, when the mixtape is in use.
|
|
413
405
|
|
|
@@ -431,8 +423,6 @@ user_can_add:
|
|
|
431
423
|
skip_note: What remains weaker if the user skips for now.
|
|
432
424
|
```
|
|
433
425
|
|
|
434
|
-
> TODO: Insert a sample `working/04-quality-checks.md` from the Cowork synthesis. The full structure with each test, the finding, and the resulting action is the most useful worked example in this file.
|
|
435
|
-
|
|
436
426
|
---
|
|
437
427
|
|
|
438
428
|
## A note on fresh attention
|
|
@@ -16,8 +16,6 @@ This tactic is the single highest-leverage move for discovering primary document
|
|
|
16
16
|
|
|
17
17
|
**How to apply:** Open the most credible source you have. Scan the references, footnotes, or "further reading" section. Note every source that's cited *and* recurs in another credible source's references. Recurrence across multiple credible sources is the signal — it's how you find the references nobody links anymore.
|
|
18
18
|
|
|
19
|
-
> TODO: Insert worked example from the Cowork CLI/TUI synthesis. Look for a moment in the research where citation-chasing surfaced a canonical source that didn't show up in any initial keyword search. Form Design Patterns by Adam Silver is a candidate — it's cited across multiple Phase 1 sources but didn't surface from "CLI wizard design" searches.
|
|
20
|
-
|
|
21
19
|
---
|
|
22
20
|
|
|
23
21
|
## 2. Reverse-engineer experts' reading lists
|
|
@@ -30,8 +28,6 @@ Are.na deserves a specific note: it's a network designed for visual and textual
|
|
|
30
28
|
|
|
31
29
|
**How to apply:** Find three to five experts in the domain. Search each one's name plus "reading list" or "syllabus" or "references." Catalog what they recommend. Cross-reference with the candidates already on your long-list — overlaps are strong signal; uniques are leads.
|
|
32
30
|
|
|
33
|
-
> TODO: Insert worked example from the Cowork CLI/TUI synthesis. Look for a tactical mention of an expert reading list that surfaced relevant work. If none exists, this section can use an example from a different domain — the methodology generalizes.
|
|
34
|
-
|
|
35
31
|
---
|
|
36
32
|
|
|
37
33
|
## 3. Mine course syllabi
|
|
@@ -49,8 +45,6 @@ University courses, bootcamp curricula, and serious online courses have already
|
|
|
49
45
|
|
|
50
46
|
Course syllabi skew toward foundations. They're best for the early-section knowledge-map buckets. Recent practitioner work is rarely on them.
|
|
51
47
|
|
|
52
|
-
> TODO: Insert worked example. If no syllabus surfaced in the CLI/TUI research, note this and use a hypothetical that's specific enough to be useful.
|
|
53
|
-
|
|
54
48
|
---
|
|
55
49
|
|
|
56
50
|
## 4. Find who experts cite
|
|
@@ -61,8 +55,6 @@ This tactic is structurally similar to citation-chasing (#1), but starts from pe
|
|
|
61
55
|
|
|
62
56
|
**How to apply:** Identify three to five practitioners credible in the domain. Open their most recent significant work. Note the sources they cite. Open the sources cited by two or more practitioners. Those are your high-priority candidates.
|
|
63
57
|
|
|
64
|
-
> TODO: Insert worked example from CLI/TUI research. Carolyn Van Slyck, Aanand Prasad (clig.dev), Will McGugan (Textualize), and Amanda Pinsker (GitHub CLI) are candidates whose citation patterns could be traced.
|
|
65
|
-
|
|
66
58
|
---
|
|
67
59
|
|
|
68
60
|
## 5. Conference proceedings
|
|
@@ -73,8 +65,6 @@ Going through three years of a specific conference is more efficient than topic-
|
|
|
73
65
|
|
|
74
66
|
Conference talks vary widely in density. The same talk reposted across multiple conferences is one signal of substance. Talks from speakers who are also cited by other practitioners (tactic #4) are another.
|
|
75
67
|
|
|
76
|
-
> TODO: Insert worked example. The CLI/TUI corpus has multiple Van Slyck talks across GopherCon and other venues — a real example of how conference-proceeding mining surfaced both her work and what to keep when the same talk appears at multiple conferences.
|
|
77
|
-
|
|
78
68
|
---
|
|
79
69
|
|
|
80
70
|
## 6. Ask the AI to find gaps, not sources
|
|
@@ -87,8 +77,6 @@ AI is bad at recall — at remembering and surfacing sources you don't know abou
|
|
|
87
77
|
|
|
88
78
|
This tactic is structurally related to the framing-gap test in Phase 5, but earlier and lower-stakes. Doing it in Phase 2 is cheaper than discovering the gap in Phase 5 and having to backtrack.
|
|
89
79
|
|
|
90
|
-
> TODO: Insert worked example from the Cowork synthesis. The Cowork run discovered that OpenClaw's initial 50-source list missed "the entire wizard/form-design tradition (Form Design Patterns, NN/g articles, Tidwell, Cooper)" — this is the canonical example of gap-finding working. Pull the specific moment where the gap was named and how it changed the candidate pool.
|
|
91
|
-
|
|
92
80
|
---
|
|
93
81
|
|
|
94
82
|
## 7. Search for the core action and the curator anchors
|
|
@@ -171,8 +171,6 @@ Drop unless the source encodes a genuinely transferable pattern. A Ratatui tutor
|
|
|
171
171
|
|
|
172
172
|
A source flagged as "low-value" during candidate discovery (Phase 2) sometimes turns out to be the only one that addresses a specific gap once you've actually read every candidate. If a low-priority source uniquely covers a knowledge-map section that would otherwise be empty or thin, rescue it. Mark the decision and the rationale clearly.
|
|
173
173
|
|
|
174
|
-
> TODO: Insert worked example from the Cowork CLI/TUI synthesis. The canonical example is the Caligula segment inside transcript #34 "some cool Linux programs you've never seen" — OpenClaw flagged it as lower-value, Cowork rescued it as "the closest direct precedent in your whole corpus." This is the textbook rescue move. Pull the specific decision and the rationale used.
|
|
175
|
-
|
|
176
174
|
### Author overrepresentation
|
|
177
175
|
|
|
178
176
|
Three of five sources in a section are by the same author. This narrows perspective and reduces the AI's ability to synthesize across views. Keep the single strongest piece by that author; replace the others with sources by different practitioners. The exception: if the author has genuinely written the canonical work in multiple sub-areas, and no other practitioner has equivalent work, keeping multiple pieces is justified — but you should be able to defend it.
|
|
@@ -209,5 +207,3 @@ candidates:
|
|
|
209
207
|
```
|
|
210
208
|
|
|
211
209
|
For dropped sources, the rationale should name *why* dropped — "duplicates Source 4," "shallow listicle," "AI-generated," "off-topic relative to JTBD." Generic "low quality" is not useful. Be specific.
|
|
212
|
-
|
|
213
|
-
> TODO: Insert two or three worked evaluation entries pulled from the Cowork synthesis — one keep with rating 5, one trim with rating 3, one drop with a specific rationale. These are the highest-leverage examples in the file.
|
|
@@ -134,9 +134,13 @@ If the synthesis names source numbers ("Source 1 argues..."), it's probably synt
|
|
|
134
134
|
|
|
135
135
|
## Worked examples
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
Good synthesis shape:
|
|
138
138
|
|
|
139
|
-
>
|
|
139
|
+
> This corpus treats onboarding as a trust-building sequence, not as a checklist. The useful question is not "which screens does the user see?" but "what does each step prove before asking for the next commitment?" Sources disagree on how much explanation belongs up front, but they converge on one rule: every prompt should reduce uncertainty before it increases work.
|
|
140
|
+
|
|
141
|
+
Bad synthesis-as-recap shape:
|
|
142
|
+
|
|
143
|
+
> Source 1 explains onboarding screens. Source 2 covers empty states. Source 3 discusses progressive disclosure. Together, these sources show that onboarding is important.
|
|
140
144
|
|
|
141
145
|
---
|
|
142
146
|
|
|
@@ -16,11 +16,20 @@ export function validatePhaseArtifact(project, phaseId) {
|
|
|
16
16
|
case "candidates":
|
|
17
17
|
return validateCandidateLonglist(join(project, "working/02-candidate-longlist.md"));
|
|
18
18
|
case "evaluation":
|
|
19
|
-
return
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
19
|
+
return validateProjectEvaluation(project);
|
|
20
|
+
case "quality": {
|
|
21
|
+
const quality = validateQualityChecks(join(project, "working/04-quality-checks.md"));
|
|
22
|
+
if (!quality.ok)
|
|
23
|
+
return quality;
|
|
24
|
+
const evaluation = validateProjectEvaluation(project);
|
|
25
|
+
if (!evaluation.ok) {
|
|
26
|
+
return {
|
|
27
|
+
ok: false,
|
|
28
|
+
message: `working/03-evaluation.yaml is invalid after quality checks: ${evaluation.message}`,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
return quality;
|
|
32
|
+
}
|
|
24
33
|
case "synthesis":
|
|
25
34
|
return validateSynthesis(join(project, "synthesis.md"));
|
|
26
35
|
case "assembly":
|
|
@@ -29,10 +38,65 @@ export function validatePhaseArtifact(project, phaseId) {
|
|
|
29
38
|
evaluationPath: join(project, "working/03-evaluation.yaml"),
|
|
30
39
|
sourceManifestPath: join(project, "local-sources/sources-manifest.yaml"),
|
|
31
40
|
});
|
|
41
|
+
case "improvement":
|
|
42
|
+
return validateImprovementDelta(join(project, ".liner-runs/improvement/delta.yaml"));
|
|
32
43
|
default:
|
|
33
44
|
return { ok: true };
|
|
34
45
|
}
|
|
35
46
|
}
|
|
47
|
+
function validateProjectEvaluation(project) {
|
|
48
|
+
return validateEvaluation(join(project, "working/03-evaluation.yaml"), {
|
|
49
|
+
expectedCandidateCount: countCandidateUrlsFromLonglist(join(project, "working/02-candidate-longlist.md")),
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
export function validateImprovementDelta(path) {
|
|
53
|
+
const parsed = parseYaml(path, "improvement delta");
|
|
54
|
+
if (!parsed.ok)
|
|
55
|
+
return parsed;
|
|
56
|
+
if (!isRecord(parsed.value)) {
|
|
57
|
+
return { ok: false, message: ".liner-runs/improvement/delta.yaml is not a YAML mapping" };
|
|
58
|
+
}
|
|
59
|
+
if (stringField(parsed.value, "contract") !== "liner.improvement_delta" || parsed.value["version"] !== 1) {
|
|
60
|
+
return { ok: false, message: ".liner-runs/improvement/delta.yaml has an unsupported contract or version" };
|
|
61
|
+
}
|
|
62
|
+
if (!stringField(parsed.value, "summary")) {
|
|
63
|
+
return { ok: false, message: ".liner-runs/improvement/delta.yaml summary is required" };
|
|
64
|
+
}
|
|
65
|
+
const removals = parsed.value["removals"];
|
|
66
|
+
const replacements = parsed.value["replacements"];
|
|
67
|
+
if (!Array.isArray(removals) || removals.length !== 0 || !Array.isArray(replacements) || replacements.length !== 0) {
|
|
68
|
+
return { ok: false, message: "Improve Corpus requires separate explicit curator intent for removals or replacements" };
|
|
69
|
+
}
|
|
70
|
+
const additions = parsed.value["additions"];
|
|
71
|
+
if (!Array.isArray(additions) || additions.length === 0) {
|
|
72
|
+
return { ok: false, message: ".liner-runs/improvement/delta.yaml must contain at least one focused addition" };
|
|
73
|
+
}
|
|
74
|
+
for (let i = 0; i < additions.length; i++) {
|
|
75
|
+
const source = additions[i];
|
|
76
|
+
if (!isRecord(source)) {
|
|
77
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}] is not a mapping` };
|
|
78
|
+
}
|
|
79
|
+
const type = stringField(source, "type");
|
|
80
|
+
if (!SOURCE_TYPES.has(type)) {
|
|
81
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}].type is invalid: ${type || "(empty)"}` };
|
|
82
|
+
}
|
|
83
|
+
if ((type === "web" || type === "youtube") && !stringField(source, "url")) {
|
|
84
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}].url is required` };
|
|
85
|
+
}
|
|
86
|
+
if (type === "local_file" && !stringField(source, "path")) {
|
|
87
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}].path is required` };
|
|
88
|
+
}
|
|
89
|
+
if (type === "skill" && !stringField(source, "path") && !stringField(source, "url")) {
|
|
90
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}] needs path or url` };
|
|
91
|
+
}
|
|
92
|
+
const priority = stringField(source, "priority");
|
|
93
|
+
const kind = stringField(source, "kind");
|
|
94
|
+
if (!PRIORITIES.has(priority) || !KINDS.has(kind)) {
|
|
95
|
+
return { ok: false, message: `.liner-runs/improvement/delta.yaml additions[${i}] needs valid priority and kind` };
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return { ok: true };
|
|
99
|
+
}
|
|
36
100
|
export function validateCandidateLonglist(path) {
|
|
37
101
|
if (!existsSync(path)) {
|
|
38
102
|
return { ok: false, message: `${path} is missing` };
|