dorfl 0.12.0 → 0.13.1
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/dist/advance.d.ts +8 -1
- package/dist/advance.d.ts.map +1 -1
- package/dist/advance.js +39 -6
- package/dist/advance.js.map +1 -1
- package/dist/apply-decide.d.ts +7 -1
- package/dist/apply-decide.d.ts.map +1 -1
- package/dist/apply-decide.js +23 -10
- package/dist/apply-decide.js.map +1 -1
- package/dist/apply-persist.d.ts +52 -8
- package/dist/apply-persist.d.ts.map +1 -1
- package/dist/apply-persist.js +78 -9
- package/dist/apply-persist.js.map +1 -1
- package/dist/do.d.ts.map +1 -1
- package/dist/do.js +71 -2
- package/dist/do.js.map +1 -1
- package/dist/frontmatter.d.ts +17 -10
- package/dist/frontmatter.d.ts.map +1 -1
- package/dist/frontmatter.js +3 -3
- package/dist/frontmatter.js.map +1 -1
- package/dist/pi-harness.d.ts +5 -0
- package/dist/pi-harness.d.ts.map +1 -1
- package/dist/pi-harness.js +93 -2
- package/dist/pi-harness.js.map +1 -1
- package/dist/protocol/WORK-CONTRACT.md +2 -1
- package/dist/reap-agent-tree.d.ts.map +1 -1
- package/dist/reap-agent-tree.js +19 -3
- package/dist/reap-agent-tree.js.map +1 -1
- package/dist/skills/setup/protocol/WORK-CONTRACT.md +2 -1
- package/dist/skills/triage-observations/SKILL.md +1 -1
- package/dist/triage-gate.d.ts +4 -2
- package/dist/triage-gate.d.ts.map +1 -1
- package/dist/triage-gate.js.map +1 -1
- package/dist/triage-persist.d.ts +55 -5
- package/dist/triage-persist.d.ts.map +1 -1
- package/dist/triage-persist.js +68 -7
- package/dist/triage-persist.js.map +1 -1
- package/package.json +1 -1
- package/src/advance.ts +52 -4
- package/src/apply-decide.ts +23 -10
- package/src/apply-persist.ts +86 -9
- package/src/do.ts +88 -2
- package/src/frontmatter.ts +17 -10
- package/src/pi-harness.ts +102 -2
- package/src/reap-agent-tree.ts +19 -3
- package/src/triage-gate.ts +4 -2
- package/src/triage-persist.ts +110 -9
package/src/triage-persist.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {readFileSync} from 'node:fs';
|
|
1
|
+
import {readFileSync, writeFileSync} from 'node:fs';
|
|
2
2
|
import {join} from 'node:path';
|
|
3
3
|
import {run, type RunResult} from './git.js';
|
|
4
4
|
import {workItemRel} from './work-layout.js';
|
|
@@ -25,8 +25,12 @@ import {setFrontmatterMarker} from './frontmatter.js';
|
|
|
25
25
|
* 1. **the conservative auto-disposition** ({@link autoDispositionObservation},
|
|
26
26
|
* US #17, `observationTriage: 'auto'`-gated): act on the no-question case on
|
|
27
27
|
* the UNTRIAGED observation in ONE local commit. BOTH no-question cases now
|
|
28
|
-
* DISCHARGE the redundant note BY DELETION
|
|
29
|
-
*
|
|
28
|
+
* DISCHARGE the redundant note BY DELETION — an AUTO disposition never RESTS a
|
|
29
|
+
* note, because both of its cases (duplicate / map) are by definition notes
|
|
30
|
+
* that carry no unique signal (task `agentic-apply-retire-disposition-
|
|
31
|
+
* vocabulary`; the ONE case that does rest a note is the human-answered
|
|
32
|
+
* `resolve` verdict on the APPLY rung, see ADR `resolve-settles-the-question-
|
|
33
|
+
* loop-not-the-note`):
|
|
30
34
|
* - `duplicate` → `git rm` the duplicate in a standalone commit, the
|
|
31
35
|
* duplicated-of identity + reason in the commit message (git history =
|
|
32
36
|
* archive). A duplicate is a redundant copy of an already-captured signal,
|
|
@@ -34,7 +38,6 @@ import {setFrontmatterMarker} from './frontmatter.js';
|
|
|
34
38
|
* - `map` → the note is already covered by the existing item it maps onto, so
|
|
35
39
|
* it is settled — `git rm` it in a standalone commit, the mapped-onto
|
|
36
40
|
* identity + reason recorded in the commit message (mirroring `duplicate`).
|
|
37
|
-
* There is no resting `triaged:keep` note any more.
|
|
38
41
|
* 2. **promote → SELF-CONTAINED new-item creation + DELETE through the CAS**
|
|
39
42
|
* ({@link promoteObservation}, US #1/#3/#8): an ANSWERED "promote" drafts a
|
|
40
43
|
* new `work/tasks/ready/<new-slug>.md` whose body is built FROM the
|
|
@@ -120,6 +123,102 @@ export class TriagePersistError extends Error {
|
|
|
120
123
|
}
|
|
121
124
|
}
|
|
122
125
|
|
|
126
|
+
// --- Back-stamping a KEPT note that was resolved before the marker existed ---
|
|
127
|
+
|
|
128
|
+
export interface StampTriagedMarkerOptions {
|
|
129
|
+
/** Working clone/worktree the stamp commits in. */
|
|
130
|
+
cwd: string;
|
|
131
|
+
/** The namespaced observation identity (`observation:<slug>`). */
|
|
132
|
+
item: string;
|
|
133
|
+
/** The observation file path RELATIVE to `cwd`. */
|
|
134
|
+
itemPath: string;
|
|
135
|
+
/** The `triaged:` value to stamp (the apply rung's settled disposition). */
|
|
136
|
+
value: string;
|
|
137
|
+
/** Why the stamp is being back-filled (rides the commit message). */
|
|
138
|
+
reason: string;
|
|
139
|
+
/** Advisory committer id for the commit subject. Defaults to git user.name. */
|
|
140
|
+
by?: string;
|
|
141
|
+
/** Environment for child git processes. */
|
|
142
|
+
env?: NodeJS.ProcessEnv;
|
|
143
|
+
/** Sink for human-readable progress notes. */
|
|
144
|
+
note?: (message: string) => void;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
export interface StampTriagedMarkerResult {
|
|
148
|
+
/** The commit sha the stamp produced, or `undefined` when the body was already marked. */
|
|
149
|
+
commit?: string;
|
|
150
|
+
/** A human-readable summary. */
|
|
151
|
+
message: string;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Stamp the `triaged:` settled marker onto an observation that was ALREADY
|
|
156
|
+
* resolved-and-kept, in ONE local commit — the SELF-HEALING back-fill for notes
|
|
157
|
+
* resolved BEFORE the apply rung learned to stamp it (ADR
|
|
158
|
+
* `resolve-settles-the-question-loop-not-the-note`).
|
|
159
|
+
*
|
|
160
|
+
* Why a back-fill exists at all: the fix that makes `resolve` stamp the marker is
|
|
161
|
+
* forward-only, so every note a repo resolved under the old code still rests
|
|
162
|
+
* `needsAnswers:false` + no sidecar + NO marker — the exact shape the triage rung
|
|
163
|
+
* re-asks. Those notes are not hypothetical (a single `rocketh` cycle re-asked
|
|
164
|
+
* four, with eleven more queued behind them), and they are un-fixable from the
|
|
165
|
+
* human's side: answering again just resolves again into the same shape.
|
|
166
|
+
*
|
|
167
|
+
* The trigger is PROOF, not a heuristic: the caller fires this only when the body
|
|
168
|
+
* carries the ENGINE-WRITTEN `## Applied answers` record, which only
|
|
169
|
+
* `apply-persist.ts` writes and only after a human answered every open question.
|
|
170
|
+
* A hand-written note cannot accidentally acquire it, and the stamp is exactly
|
|
171
|
+
* what the apply rung WOULD have written had it known how.
|
|
172
|
+
*
|
|
173
|
+
* ONE commit touching ONE file, so the tree-less publish (`pushTreelessResult`)
|
|
174
|
+
* carries it to the arbiter like any other triage-rung marker write; once landed
|
|
175
|
+
* the note drops out of the triage pool and this path is never taken again.
|
|
176
|
+
*/
|
|
177
|
+
export function stampTriagedMarker(
|
|
178
|
+
options: StampTriagedMarkerOptions,
|
|
179
|
+
): StampTriagedMarkerResult {
|
|
180
|
+
const {cwd, item, itemPath, value, reason, env} = options;
|
|
181
|
+
const note = options.note ?? (() => {});
|
|
182
|
+
|
|
183
|
+
if (gitSoft(['rev-parse', '--git-dir'], cwd, env).status !== 0) {
|
|
184
|
+
throw new TriagePersistError('not inside a git repository');
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const abs = join(cwd, itemPath);
|
|
188
|
+
const before = readFileSync(abs, 'utf8');
|
|
189
|
+
const after = setFrontmatterMarker(before, 'triaged', value);
|
|
190
|
+
if (after === before) {
|
|
191
|
+
// Already marked (or a malformed fence `setFrontmatterMarker` refuses to
|
|
192
|
+
// rewrite) — nothing to commit; never produce an empty commit.
|
|
193
|
+
const message = `triage ${item}: already carries triaged:${value} — no stamp needed.`;
|
|
194
|
+
note(message);
|
|
195
|
+
return {message};
|
|
196
|
+
}
|
|
197
|
+
writeFileSync(abs, after);
|
|
198
|
+
const by = options.by || resolveBy(cwd, env);
|
|
199
|
+
gitHard(['add', '--', itemPath], cwd, env);
|
|
200
|
+
const subject = `advance: triage ${item} → settled (by ${by})`;
|
|
201
|
+
gitHard(
|
|
202
|
+
[
|
|
203
|
+
'commit',
|
|
204
|
+
'--quiet',
|
|
205
|
+
'-m',
|
|
206
|
+
subject,
|
|
207
|
+
'-m',
|
|
208
|
+
`triaged: ${value}\n\n${reason}`,
|
|
209
|
+
],
|
|
210
|
+
cwd,
|
|
211
|
+
env,
|
|
212
|
+
);
|
|
213
|
+
const commit = gitHard(['rev-parse', 'HEAD'], cwd, env).stdout.trim();
|
|
214
|
+
const message =
|
|
215
|
+
`triage ${item}: back-stamped triaged:${value} (the note was already ` +
|
|
216
|
+
'resolved-and-kept — it carries an engine-written applied-answers record) ' +
|
|
217
|
+
'so the triage rung stops re-asking its settled question.';
|
|
218
|
+
note(message);
|
|
219
|
+
return {commit, message};
|
|
220
|
+
}
|
|
221
|
+
|
|
123
222
|
// --- The conservative auto-disposition (US #17) ---------------------------
|
|
124
223
|
|
|
125
224
|
export interface AutoDispositionOptions {
|
|
@@ -149,8 +248,10 @@ export interface AutoDispositionResult {
|
|
|
149
248
|
* DELETION (`git rm` in a standalone commit, the reason in the message). A
|
|
150
249
|
* `duplicate` is a redundant copy of `existing`; a `map` is already covered by
|
|
151
250
|
* `existing` — either way the note carries no unique signal, so it leaves the
|
|
152
|
-
* inbox by being gone.
|
|
153
|
-
* `agentic-apply-retire-disposition-vocabulary`)
|
|
251
|
+
* inbox by being gone. An AUTO disposition never RESTS a note (task
|
|
252
|
+
* `agentic-apply-retire-disposition-vocabulary`); resting a KEPT note is the
|
|
253
|
+
* human-answered `resolve` verdict's job on the apply rung (ADR
|
|
254
|
+
* `resolve-settles-the-question-loop-not-the-note`). NEVER an auto-delete of a
|
|
154
255
|
* NON-redundant signal.
|
|
155
256
|
*/
|
|
156
257
|
outcome: 'deleted';
|
|
@@ -167,9 +268,9 @@ export interface AutoDispositionResult {
|
|
|
167
268
|
* ONE local commit, no question surfaced. BOTH no-question cases DISCHARGE the
|
|
168
269
|
* redundant note BY DELETION (`git rm` in a STANDALONE commit, the mapped/
|
|
169
270
|
* duplicated-of identity + reason in the commit message; git history = archive).
|
|
170
|
-
*
|
|
171
|
-
* `agentic-apply-retire-disposition-vocabulary`
|
|
172
|
-
* acted-on, or deleted
|
|
271
|
+
* An AUTO disposition never RESTS a note (task
|
|
272
|
+
* `agentic-apply-retire-disposition-vocabulary`): its two cases carry no unique
|
|
273
|
+
* signal, so they are still-open, acted-on, or deleted — never kept:
|
|
173
274
|
*
|
|
174
275
|
* - `duplicate` → the note is an EXACT duplicate of `existing` (already
|
|
175
276
|
* captured); the original carries the signal, so the copy is deleted; or
|