tldr-experts 0.7.0 → 0.8.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/CHANGELOG.md CHANGED
@@ -1,5 +1,71 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.8.0 — 2026-09-04
4
+
5
+ ### Added
6
+
7
+ - **`tldrx drive --tldr` — essentials only, for a run whose trail nobody will read.** It adds
8
+ one section to either mandate and stamps the header `· tldr ·`. The session reports in a
9
+ fixed shape — what `tldrx run status` already prints (phases, percentages, spend against the
10
+ ceiling, what is next) plus **at most three bullets of delta** — and stops narrating: no
11
+ recap of a sub-agent's report, no summary of a diff, no restating the status block in prose.
12
+ Free text is reserved for a strict blocker's guided question and for a correction.
13
+ It also turns off the half of the trail nothing consumes: no `tldrx note`, and gate evidence
14
+ at the template's minimum. A fact that must outlive the turn goes to `tldrx facts add`, which
15
+ every later prompt **does** read.
16
+ Measured on a ten-run workspace: of ~4.0 MB written, 2.16 MB is trail, and all **261**
17
+ declared stage `inputs:` contain **zero** occurrences of `handoff.md`, `retro.md` or
18
+ `gate-evidence` — ~445k tokens of output across those runs that no prompt ever reads back.
19
+ Operator notes alone are 133,689 B.
20
+ What `--tldr` deliberately does **not** do is drop the handoff: `claim-sources` is condition 5
21
+ of the seven `auto` conditions and runs whether or not a stage declared it, so a run without
22
+ one cannot close an `auto` or `agent` gate. The mandate briefs sub-agents to trim the *prose*
23
+ and never the `[src: …]` citations, and says why. `--tldr` works on `--attended` too — terse
24
+ output is orthogonal to who signs. Absence is today: without the flag both mandates render
25
+ byte-identically to before, and a test asserts it.
26
+ - `MANDATE_TLDR_MAX_LINES` (`165`) bounds the `--tldr` variants; the standard mandate keeps the
27
+ tighter `MANDATE_MAX_LINES`. Two constants rather than one looser one, so the terse mode does
28
+ not spend every other run's skimmability budget.
29
+
30
+ ### Fixed
31
+
32
+ - **`tldrx drive --unattended` told the driver four times to stop and never once to
33
+ continue, and the runs it drove did exactly that.** Measured over the eight driven runs
34
+ of a real workspace: 26 `budget.raised` and 26 `question.answered` events, and an owner
35
+ who had to type *"sigue con todas desatendido, no esperes por mi"* **inside** an
36
+ unattended run to restart a session the mandate had correctly halted. `grep -ic
37
+ "continue|keep going|proceed|do not stop|resume"` over `mandate.ts` returned `0`. The
38
+ unattended mandate now opens the discipline with a **`## Do not stop`** section that
39
+ defines the only thing that may halt a run — a STRICT blocker, one where no remaining
40
+ turn can proceed until the owner answers — and makes the driver **name the work the
41
+ blocker does not block** before it may call one strict. The three remaining halts are
42
+ narrowed to match: the preflight refusal is now *asked* rather than gone quiet on, the
43
+ budget bullet keeps "do not raise one, do not route around one" but no longer halts the
44
+ run (it asks, then keeps spending what the ceiling still funds), and the interrupt list
45
+ is strict blockers only, "never as a bare halt".
46
+ - **A parked question is now a GUIDED question.** "State the question in one sentence" got
47
+ open prompts nobody could answer from a phone, so a product question stopped a run for
48
+ hours. Parking now asks for 2–5 lettered options with their consequences, what the run's
49
+ own docs and facts already decide, the option the driver would take, and what it will do
50
+ if no answer arrives. Both modes carry it.
51
+ - **The old halt licence is gone.** "If the only safe version is *do nothing yet*, do
52
+ nothing yet and park it" was true about the write and read as true about the run. The
53
+ text now says which it means: not shipping an unguarded write is not the same as not
54
+ shipping anything.
55
+
56
+ ### Changed
57
+
58
+ - **The ask channel is the console, and the framework stays agnostic about anything else.**
59
+ The mandate says *"Ask on the console, unless my launch message named another channel"* —
60
+ no chat vendor is named in shipped text, and a test asserts none ever is, so one
61
+ operator's bridge never becomes a dependency of everybody's run. A default the driver
62
+ falls back on when no answer reaches it is recorded as the **driver's** decision and may
63
+ never be cited back as the owner's — the distinction one run drew by hand and the text
64
+ now carries.
65
+ - `MANDATE_MAX_LINES` moved once, `120` → `140`, with the reason recorded in the source.
66
+ The bound is still real and still asserted; the unattended mandate renders 137 lines and
67
+ the attended one 123. File formats remain `version: 1`.
68
+
3
69
  ## 0.7.0 — 2026-09-03
4
70
 
5
71
  ### Added
package/README.md CHANGED
@@ -75,14 +75,30 @@ Two commands and a prompt — and the prompt now ships with the package:
75
75
  ```bash
76
76
  tldrx drive --unattended # print the mandate; paste it into the session that drives the run
77
77
  tldrx drive --attended # the same disciplines, but every gate stays yours to sign
78
+ tldrx drive --unattended --tldr # essentials only, for a run whose trail you will not read
78
79
  ```
79
80
 
80
81
  `tldrx drive` needs no workspace, opens no run and writes nothing: it prints the discipline the
81
82
  first real runs were driven by — the three-role protocol (developer → a **fresh** adversarial
82
83
  reviewer, never the author → the host verifying both in the code, not in their reports), evidence
83
- labelled `measured` / `inferred` / `assumed`, product questions parked rather than decided, the
84
- reviewer calibrated to the story's stakes, and the cost declared once. The two modes differ in
85
- exactly two places: who drives the turns, and who may close a gate.
84
+ labelled `measured` / `inferred` / `assumed`, product questions parked as **guided** ones rather
85
+ than decided, the reviewer calibrated to the story's stakes, and the cost declared once. The two
86
+ modes differ in exactly two places: who drives the turns, and who may close a gate.
87
+
88
+ **The unattended mandate leads with `## Do not stop`.** A run only ends early because the session
89
+ decides to, so the text defines the one thing that may end it — a strict blocker, where no
90
+ remaining turn can proceed until you answer — and makes the driver name the work a blocker does
91
+ *not* block before it may halt for it. Everything short of that is parked as a guided question
92
+ (lettered options, the option the driver would take, asked on the console unless your launch
93
+ message names another channel) and the run carries on down every path the question does not block.
94
+
95
+ **`--tldr` is for the runs you will not audit.** The session reports what `tldrx run status`
96
+ already prints — phases, percentages, spend against the ceiling, what is next — plus at most three
97
+ bullets of delta, and stops narrating. It also drops the half of the trail nothing consumes:
98
+ measured across ten real runs, of ~4.0 MB written 2.16 MB is trail, and all 261 declared stage
99
+ `inputs:` contain **zero** references to `handoff.md`, `retro.md` or `gate-evidence`. It is a
100
+ reporting contract, not a quality setting — the evidence discipline and the gate checks are
101
+ untouched, and handoffs keep their citations because `claim-sources` gates on them.
86
102
 
87
103
  The rest of this section is what that mandate says, in the shape you would type it by hand.
88
104
 
@@ -298,6 +314,7 @@ back on the registry is 0.3.0.
298
314
 
299
315
  | Version | Date | Status | Contains |
300
316
  |---|---|---|---|
317
+ | 0.8.0 | 2026-09-04 | `beta` | the unattended mandate learns to keep going: a `## Do not stop` section that defines the one thing allowed to end a run early (a strict blocker, named against the work it does not block), product questions parked as **guided** ones with lettered options and a pre-declared fallback, and a budget stop that asks instead of halting — written against 26 `budget.raised` and 26 `question.answered` events on a real ten-run workspace where the owner had to re-authorise "unattended" mid-run. Plus `tldrx drive --tldr`: a reporting contract for runs nobody will audit — the `run status` block plus three bullets of delta, no operator notes, minimal gate evidence, handoffs trimmed of prose but never of the citations `claim-sources` gates on. The ask channel stays the console and the framework names no chat vendor |
301
318
  | 0.7.0 | 2026-09-03 | `beta` | Codex as a second honest automated runner: recorded JSONL contract, structured envelopes, role-based sandboxes, token/session provenance, and explicitly unmetered USD accounting; Claude remains the default and the pilot harness. Also absorbs the citation-honesty work previously staged as 0.6.2: a `file` src resolves against the branches the run RECORDED and NAMES the unmerged ref instead of passing in silence or breaking with the temp dir (#140), watcher cards name it the same way (#143), and every run close reports the questions nobody answered (#141) |
302
319
  | 0.6.1 | 2026-09-03 | `beta` | dogfooding fixes from the first fully-unattended runs: blocked stories never lose uncommitted work (rescue commits + `story.work_rescued`), a fix is only Resolved with a reachable sha, re-entered stages reconstruct their handoff from the ledger instead of degrading it, the Cost header reports the phase and names its lower bound (shared `spendBasis`), feature presets resolve their per-repo maps, Plan sees the command allowlist its gate enforces, the landing sells the unattended flow |
303
320
  | 0.6.0 | 2026-09-02 | `beta` | the dashboard suite — a "Now" hero strip, `--serve` live refresh, stage durations and gate notes on page and CLI, and a public demo generated from fixtures; honest dual-economy spend (metered + host, lower-bound named); gate provenance — `executed_by` + `authority` so a delegated signature never reads as a personal one, machine-signed reporting fixed; ONE `absent:` semantic shared by claim-sources and the auto gate; superseded stamps when an owner answer flips an earlier phase doc; run close commits its state and `ship` refuses a state-carrying epic; merge-wave gates `docs:build`, survives interruption and self-rewrite; a public-surface drift guard; env.yml validation (unique ids, tool cap) |
package/dist/tldrx.js CHANGED
@@ -15274,11 +15274,17 @@ var ENTRIES = [
15274
15274
  name: "unattended",
15275
15275
  arg: null,
15276
15276
  meaning: "Nobody is watching. The mandate is for a session driving an `attended_by: host` run with `agent` gates: it drives every turn, signs a gate only over a written evidence note, and wakes a person for the four things that are still theirs."
15277
+ },
15278
+ {
15279
+ name: "tldr",
15280
+ arg: null,
15281
+ meaning: "Essentials only, for a run whose trail you will not read. The mandate gains a reporting contract: after every commit and at every gate the session shows what `tldrx run status` prints plus at most three bullets of delta, and nothing else — no recaps, no diff summaries, no `tldrx note`. Sub-agents are briefed to keep handoffs and evidence notes at the minimum `claim-sources` still validates. Prose is trimmed; citations and gates are not. Works with either mode."
15277
15282
  }
15278
15283
  ],
15279
15284
  examples: [
15280
15285
  "tldrx drive --unattended",
15281
15286
  "tldrx drive --unattended 260901-leaderboard",
15287
+ "tldrx drive --unattended --tldr",
15282
15288
  "tldrx drive --attended"
15283
15289
  ],
15284
15290
  exits: [EXIT_OK, EXIT_USAGE],
@@ -46445,24 +46451,26 @@ function option3(argv, name) {
46445
46451
  var DRIVE_MODES = ["attended", "unattended"];
46446
46452
  var RULE = "-".repeat(78);
46447
46453
  var RUN_PLACEHOLDER = "<run>";
46448
- function renderMandate(mode, version, run2) {
46454
+ function renderMandate(mode, version, run2, tldr = false) {
46449
46455
  const text5 = [
46450
- ...header2(mode, version, run2),
46456
+ ...header2(mode, version, run2, tldr),
46451
46457
  ...preflight(mode),
46452
46458
  ...roles(),
46453
46459
  ...evidence(),
46460
+ ...continuation(mode),
46454
46461
  ...parking(),
46455
46462
  ...calibration(),
46456
46463
  ...budget(),
46464
+ ...reporting(tldr),
46457
46465
  ...driving(mode),
46458
46466
  ...gate2(mode)
46459
46467
  ].join(`
46460
46468
  `).trimEnd();
46461
46469
  return run2 === undefined ? text5 : text5.replaceAll(RUN_PLACEHOLDER, run2);
46462
46470
  }
46463
- function header2(mode, version, run2) {
46471
+ function header2(mode, version, run2, tldr = false) {
46464
46472
  return [
46465
- `tldrx drive — session mandate · ${mode} · tldrx ${version}`,
46473
+ `tldrx drive — session mandate · ${mode}${tldr ? " · tldr" : ""} · tldrx ${version}`,
46466
46474
  "",
46467
46475
  ...run2 === undefined ? [
46468
46476
  "Paste everything below the rule into the session that will drive the run, replacing <run>",
@@ -46496,7 +46504,8 @@ function preflight(mode) {
46496
46504
  ' `tldrx run gates set <stage>:agent --note "…"`, quoting MY delegation from the launch message.',
46497
46505
  "- BUDGET: `tldrx-work/<run>/budget.yml` exists. State the ceiling you will honour, in dollars.",
46498
46506
  "",
46499
- "Any one of the three you cannot establish: REFUSE to start, and name the command that failed.",
46507
+ "Any one of the three you cannot establish: REFUSE to start, name the command that failed,",
46508
+ "and put it to me as a guided question — a strict blocker is asked, never gone quiet on.",
46500
46509
  ""
46501
46510
  ];
46502
46511
  }
@@ -46552,23 +46561,74 @@ function evidence() {
46552
46561
  ""
46553
46562
  ];
46554
46563
  }
46564
+ function continuation(mode) {
46565
+ if (mode !== "unattended")
46566
+ return [];
46567
+ return [
46568
+ "## Do not stop",
46569
+ "",
46570
+ 'Stopping is the failure this mandate exists to prevent, and "I had a question" is not one.',
46571
+ "Halt only on a STRICT blocker: one where no remaining turn can proceed until I answer. Before",
46572
+ "you call one strict, name the work it does NOT block — the next story, wave, stage or review —",
46573
+ "and go do that first. Everything short of that you park as below, or decide and log; then",
46574
+ "carry on. If you are truly blocked on every front, that is one line and a guided question, not",
46575
+ "silence.",
46576
+ ""
46577
+ ];
46578
+ }
46555
46579
  function parking() {
46556
46580
  return [
46557
- "## Park product questions; do not decide them",
46581
+ "## Park product questions as GUIDED ones; do not decide them, and do not halt for them",
46558
46582
  "",
46559
- "A product decision is not yours. Park it as a card the same turn you hit it:",
46583
+ "A product decision is not yours to make — and it is not a reason to stop the run. Park it",
46584
+ "the same turn you hit it, then carry on down every path it does not block:",
46560
46585
  "",
46561
- "- state the question in one sentence, and what it blocks;",
46562
- "- say what the docs and the run's own facts ALREADY decide about it, with the citation, so",
46563
- " I am choosing between real options instead of re-deriving them;",
46564
- "- name the smallest guarded thing you can ship without the answer or say there is none.",
46586
+ "- the question in one sentence, and exactly what it blocks — and what it does NOT;",
46587
+ "- 2–5 lettered options, each with its consequence. Never an open prompt;",
46588
+ "- what the docs and the run's own facts ALREADY decide, cited, so I pick between real options;",
46589
+ "- the option you would take and why, and what you will do if no answer reaches you;",
46590
+ "- the smallest guarded thing you can ship without the answer — or say there is none.",
46565
46591
  "",
46566
- "An open question is never a licence to ship an unguarded write. If the only safe version is",
46567
- '"do nothing yet", do nothing yet and park it. `tldrx note <run> "…"` records the moment;',
46592
+ "Ask on the console, unless my launch message named another channel; then use that one and say",
46593
+ "so. An answer I never gave is not my decision: if you act on your own default, record it as",
46594
+ "YOURS in those words, and never cite it back to me as mine.",
46595
+ "",
46596
+ "An open question is never a licence to ship an unguarded write — but not shipping the write is",
46597
+ 'not the same as not shipping anything. `tldrx note <run> "…"` records the moment;',
46568
46598
  '`tldrx answer <Qid> "…"` is mine to type.',
46569
46599
  ""
46570
46600
  ];
46571
46601
  }
46602
+ function reporting(tldr) {
46603
+ if (!tldr)
46604
+ return [];
46605
+ return [
46606
+ "## Report terse; do not narrate",
46607
+ "",
46608
+ "I am not reading this session for its prose, so write none. After every `--commit` and at",
46609
+ "every gate, show me two things and nothing else:",
46610
+ "",
46611
+ "1. what `tldrx run status <run>` prints — it already carries the phases, the percentages, the",
46612
+ " spend against the ceiling and what is next. Do not retype any of it in words.",
46613
+ "2. at most three bullets of DELTA since the last one: what landed, what is next, what was",
46614
+ " deferred or decided. Three is a cap, not a target.",
46615
+ "",
46616
+ "Free text is for two things only: a strict blocker's guided question, and a correction to",
46617
+ "something you already told me. Not a recap of a sub-agent's report, not a summary of a diff I",
46618
+ "can read myself, not the status block again in sentences.",
46619
+ "",
46620
+ "Write no `tldrx note` on this run. Nobody will audit it, and no prompt ever reads one back — a",
46621
+ "fact that must outlive the turn is `tldrx facts add`, which every later prompt DOES read.",
46622
+ "",
46623
+ "Brief every sub-agent to keep its handoff minimal: the sections and the `[src: …]` citations",
46624
+ "`claim-sources` validates, and nothing past them. Trim the prose, never the citations — the",
46625
+ "handoff is a gate input, and one that fails the validator costs the gate you need to close.",
46626
+ "",
46627
+ "Same for the evidence note: the four H2 sections, the counts you actually measured, and",
46628
+ "`caveats: []` when there are none. It is a signature, not a report.",
46629
+ ""
46630
+ ];
46631
+ }
46572
46632
  function calibration() {
46573
46633
  return [
46574
46634
  "## Calibrate the review to the stakes",
@@ -46595,8 +46655,9 @@ function budget() {
46595
46655
  " $0.00 is a measurement, and a false one.",
46596
46656
  '- When the records are incomplete, report a floor and say it is one — "at least $4.10 across',
46597
46657
  ' the 6 turns that reported" — never a total that reads as complete.',
46598
- "- A ceiling raise is my decision. Do not raise one, and do not route around one: stop, say",
46599
- " what the remaining work costs and why, and wait.",
46658
+ "- A ceiling raise is my decision: do not raise one, and do not route around one. That is not",
46659
+ " a reason to halt the run — ask it as a guided question, say what the remaining work costs,",
46660
+ " and keep spending what the ceiling still funds. Stop only when the next turn has none left.",
46600
46661
  ""
46601
46662
  ];
46602
46663
  }
@@ -46650,9 +46711,10 @@ function gate2(mode) {
46650
46711
  "`refuse` and `sign-with-fixlist` are real verdicts — use them. A note that signs everything",
46651
46712
  "is a rubber stamp the framework will believe.",
46652
46713
  "",
46653
- "Interrupt me ONLY for: a new product decision · a budget-ceiling raise · work outside the",
46654
- "declared boundary · the final merge. Everything else you decide, and log. Never push — the",
46655
- "final merge is mine.",
46714
+ "Interrupt me ONLY for a STRICT blocker — a new product decision, a ceiling raise, or work",
46715
+ "outside the declared boundary that nothing else can proceed around and always as the",
46716
+ "guided question above, never as a bare halt. Everything else you decide, and log.",
46717
+ "Never push — the final merge is mine.",
46656
46718
  ""
46657
46719
  ];
46658
46720
  }
@@ -46683,7 +46745,7 @@ function gate2(mode) {
46683
46745
  var driveCommand = {
46684
46746
  name: "drive",
46685
46747
  summary: "Print the session mandate for driving a run",
46686
- usage: "tldrx drive <--attended|--unattended> [<run>] [--run <id>]",
46748
+ usage: "tldrx drive <--attended|--unattended> [--tldr] [<run>] [--run <id>]",
46687
46749
  subcommands: [],
46688
46750
  implemented: true,
46689
46751
  async run(argv) {
@@ -46704,7 +46766,8 @@ var driveCommand = {
46704
46766
  }
46705
46767
  const mode = attended2 ? "attended" : "unattended";
46706
46768
  const run2 = args.positionals[0] ?? stringFlag(args, "run") ?? theOneOpenRun();
46707
- process.stdout.write(`${renderMandate(mode, await frameworkVersion(), run2)}
46769
+ const tldr = boolFlag(args, "tldr");
46770
+ process.stdout.write(`${renderMandate(mode, await frameworkVersion(), run2, tldr)}
46708
46771
  `);
46709
46772
  return EXIT_OK;
46710
46773
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tldr-experts",
3
- "version": "0.7.0",
3
+ "version": "0.8.0",
4
4
  "description": "tldr-experts: an evidence-first, file-based AI development framework - five stages, a gate on every one, and every claim cited or refused. Installs the `tldrx` (and `tldr-experts`) command. Beta.",
5
5
  "license": "MIT",
6
6
  "author": "Alan Martinez",
@@ -2,7 +2,7 @@
2
2
  "$doc": "Shape verified from https://code.claude.com/docs/en/plugins.md (Quickstart > Create the plugin manifest). Fields used here: name, description, version, author.name. Only plugin.json goes inside .claude-plugin/; skills/, agents/ and hooks/ live at the plugin root.",
3
3
  "name": "tldrx",
4
4
  "description": "tldr-experts: an evidence-first, file-based AI development framework. Five stages, a gate on every one, every claim cited or refused. Beta.",
5
- "version": "0.7.0",
5
+ "version": "0.8.0",
6
6
  "author": {
7
7
  "name": "Alan Martinez"
8
8
  }