@sabaiway/agent-workflow-kit 14.21.0 → 14.22.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 +46 -0
- package/README.md +1 -1
- package/SKILL.md +1 -1
- package/capability.json +1 -1
- package/package.json +1 -1
- package/references/authoring/TASK_TEMPLATE.md +11 -16
- package/references/modes/agents.md +2 -2
- package/references/modes/procedures.md +7 -7
- package/references/modes/recipes.md +1 -1
- package/references/modes/set-recipe.md +1 -1
- package/references/modes/tier.md +1 -1
- package/references/modes/velocity.md +1 -1
- package/references/reference-profile.json +1 -1
- package/references/templates/SPEC_TEMPLATE.md +2 -1
- package/references/templates/agent_rules.md +7 -7
- package/tools/carriers.mjs +6 -4
- package/tools/cheap-agents.mjs +1 -1
- package/tools/held-session.mjs +1 -33
- package/tools/procedures.mjs +83 -113
- package/tools/rules-regions.mjs +2 -1
- package/tools/tier-guide-facts.mjs +145 -159
- package/tools/tier-guide.mjs +8 -14
package/tools/procedures.mjs
CHANGED
|
@@ -37,7 +37,7 @@ import { resolveEngineDir, readEngineFragment, PROCEDURES_FRAGMENT_REL } from '.
|
|
|
37
37
|
import { plansInFlight, PLANS_REL } from './plan-files.mjs';
|
|
38
38
|
// The family's ONE shell quoter for a RENDERED command operand (bare when the value is already safe,
|
|
39
39
|
// single-quoted otherwise) — the same leaf eight other command renderers here read through.
|
|
40
|
-
import { shellQuoteArg, isSeedablePathToken, isRenderableLine, escapeForDisplay
|
|
40
|
+
import { shellQuoteArg, isSeedablePathToken, isRenderableLine, escapeForDisplay } from './repo-lex.mjs';
|
|
41
41
|
// The config schema/read core (orchestration-config.mjs, the single config contract): the reader +
|
|
42
42
|
// the SHARED slot/recipe validity, never the fs-writer (orchestration-write.mjs) DIRECTLY — the
|
|
43
43
|
// import-split test pins the direct-import rule.
|
|
@@ -48,8 +48,6 @@ import { AUTONOMY_REL, loadAutonomy, resolveAutonomy, isSparseSeedConfig } from
|
|
|
48
48
|
// orchestration-write (the import-split test pins both direct rules; the TRANSITIVE claim is
|
|
49
49
|
// structural — test/read-graph-purity.test.mjs pins it).
|
|
50
50
|
import { resolveFlowStorePath, readFlowStore } from './flow-store-read.mjs';
|
|
51
|
-
import { readDelegationLedger } from './dispatch-store-read.mjs';
|
|
52
|
-
import { foldLaneLines, HELD_RECEIPT_BACKEND, judgeLedger } from './held-session.mjs';
|
|
53
51
|
import { CHAIN_KIND } from './flow-record.mjs';
|
|
54
52
|
import { readRegistration } from './mcp-registration.mjs';
|
|
55
53
|
// The declared source-size practice (D-17 U1), read through the practice's PURE READ core — never
|
|
@@ -166,7 +164,8 @@ const resolveAllSlots = ({ activity, config, detection, overrides, surveyLens })
|
|
|
166
164
|
const knobsFor = (cmd) => [...registry.values()].filter((k) => (k.appliesTo ?? []).includes(cmd));
|
|
167
165
|
return Object.entries(ACTIVITIES[activity].slots).map(([slot, slotType]) => {
|
|
168
166
|
const resolved = resolveActivityRecipe({ config: config ?? {}, readiness: detection, activity, slot, override: overrides[slot], surveyLens });
|
|
169
|
-
|
|
167
|
+
// The epic is reviewed by the lens alone whatever its review slot resolves to: no bridge is dispatched.
|
|
168
|
+
if (isSwitchSlot(slotType) || isEpicLensReview(activity, slot)) return { slot, slotType, ...resolved, backends: [], contracts: [], vehicles: [] };
|
|
170
169
|
// The concrete wrapper set this slot's EFFECTIVE recipe dispatches (empty for solo). Reuse
|
|
171
170
|
// planRecipe's drift-guarded dispatch for WHICH backends, then resolve each (backend, role) to its
|
|
172
171
|
// manifest wrapper cmd via the bridge registry — no wrapper name is hand-composed here. A vehicle
|
|
@@ -213,61 +212,71 @@ const SOURCE_LABEL = {
|
|
|
213
212
|
|
|
214
213
|
// The explicit wrapper set a review/execute recipe dispatches, printed beside the recipe name so the A2
|
|
215
214
|
// recipe-fidelity obligation ("run every named backend, every round") is mechanical at the point of use.
|
|
216
|
-
// ≥2 backends (Council) → the every-round reminder; exactly 1 → the lone wrapper; Solo dispatches none → ''
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
215
|
+
// ≥2 backends (Council) → the every-round reminder; exactly 1 → the lone wrapper; Solo dispatches none → '';
|
|
216
|
+
// the epic's review slot names its lens review instead.
|
|
217
|
+
const EPIC_LENS_LABEL = ' → the lens review: one review-lens read of the rendered brief; epic.review dispatches no bridge';
|
|
218
|
+
const backendSetLabel = (backends, lensReview = false) =>
|
|
219
|
+
lensReview
|
|
220
|
+
? EPIC_LENS_LABEL
|
|
221
|
+
: !backends || backends.length === 0
|
|
222
|
+
? ''
|
|
223
|
+
: backends.length >= 2
|
|
224
|
+
? ` → run every backend every round: ${backends.join(' + ')}`
|
|
225
|
+
: ` → ${backends[0]}`;
|
|
223
226
|
|
|
224
227
|
// The review-loop economics block (M1 + M6's firing half) — printed when the activity engages a review
|
|
225
228
|
// member: a slot RESOLVING reviewed | council, a roster, or one whose config or override REQUESTED a
|
|
226
229
|
// review recipe and degraded (readiness removes no configured obligation, and the table still judges
|
|
227
230
|
// it); omitted only for a solo nobody asked to be otherwise. It paraphrases the procedures.md
|
|
228
|
-
// Fold + loop step + orchestration §4 canon (no rival rule)
|
|
229
|
-
//
|
|
230
|
-
//
|
|
231
|
-
//
|
|
232
|
-
//
|
|
233
|
-
//
|
|
231
|
+
// Fold + loop step + orchestration §4 canon (no rival rule), as story-flow's review-loop part states it:
|
|
232
|
+
// one fold ask per member per round, at most two rounds with the raiser's re-read of a last-round fold,
|
|
233
|
+
// the re-check of a moved staged tree for plan-execution, backend divergence = the crossover stop, the
|
|
234
|
+
// thin-plan/diff-review carve-out, a self-consistency read before every re-review, and the REQUIRED
|
|
235
|
+
// per-round structured emission {round N · finding-origin tally · per-backend verdict}. Only a review
|
|
236
|
+
// slot can resolve or request reviewed|council (execute floors at solo|delegated), so the gate reads the
|
|
237
|
+
// recipe, the requested recipe and the roster. The epic renders its lens review whatever its slot says.
|
|
234
238
|
const REVIEW_RECIPES = new Set(['reviewed', 'council']);
|
|
235
|
-
const CONSULT_LINE = ' • Before every fold of a finding raised by a review member (a bridge backend or a placed lens): ASK
|
|
236
|
-
'Reply accept, or correct with exact replacement text."; codex: fresh codex-review plan <consult-brief> with the same payload written before the working tree changes; a placed lens: re-dispatch the same lens vehicle with the same payload. A self-review finding, or any finding when no review member ran, is folded directly — the exemption is the finding\'s ORIGIN, never the recipe word on the slot line.';
|
|
239
|
+
const CONSULT_LINE = ' • Before every fold of a finding raised by a review member (a bridge backend or a placed lens): after the round, ASK each member that raised a finding in ONE ask per round carrying all of its findings with their proposed folds, whether each fold solves its finding and adds no new problem; WAIT for its answer, READ it, then edit only as accepted or corrected — agy: agy-review --continue --decided @f --focus "Findings and proposed folds: <each finding with its exact fold>. Does each proposed fold solve its finding and add no new problem? If a finding is the second case against the same check, reply with the replacement invariant, not an added case. ' +
|
|
240
|
+
'Reply accept, or correct with exact replacement text, per fold."; codex: fresh codex-review plan <consult-brief> with the same payload written before the working tree changes; a placed lens: re-dispatch the same lens vehicle with the same payload. A self-review finding, or any finding when no review member ran, is folded directly — the exemption is the finding\'s ORIGIN, never the recipe word on the slot line.';
|
|
241
|
+
const CAP_LINE = " • Cap architecture review at ≤2 rounds, with no third round: a surviving blocker or major goes to one fold — raising it to an acceptance invariant or handing its mechanics to the diff review included — through the fold ask and its raiser's re-read, or to the maintainer, who cuts the clause or rules; never by exhausting the strictest backend.";
|
|
242
|
+
const RE_READ_LINE = " • Round two gives every member the folded artifact whole, the decided register (each round-one finding with its disposition: the fold, the debt row, or the reason it was declined) and each fold's diff; a fold of the last round is re-read by the member that raised it, and one not accepted or whose re-read is not ship-class goes to the maintainer; after the last round nothing is folded unread.";
|
|
243
|
+
const RE_CHECK_LINE = " • The re-check of a moved staged tree: when the staged tree moves after a member's last ship-class verdict (a fold of the last round, a tracked record edited, a version bumped), every member, the lens included, reads only the move with the decided register, the raiser of a folded finding judging its fold — one fresh grounded code-mode run per bridge, whose receipt binds the moved tree; a re-check that is not ship-class is never folded and re-checked again: a fold's finding goes to the maintainer, any other move is undone to the judged tree or put to the maintainer.";
|
|
244
|
+
const EPIC_LENS_LINES = [
|
|
245
|
+
'Review loop (procedures.md epic · the lens review) — whatever epic.review resolves to, no bridge run is spent on an epic:',
|
|
246
|
+
' • One review-lens read per round over the brief epic-shape-cli --review-brief <epic> renders, never the file; where no lens can run, the review closes with a stated degrade the maintainer weighs at the go.',
|
|
247
|
+
' • Before every fold of a finding the lens raised: ASK it in ONE ask per round carrying all of its findings with their proposed folds (a re-dispatch of the same lens vehicle), WAIT, READ, then fold only as accepted or corrected, through epic-shape-cli --fold, at concept altitude.',
|
|
248
|
+
' • At most two rounds: a fold of the second round is re-read by the lens or goes to the maintainer with the go.',
|
|
249
|
+
];
|
|
237
250
|
const ARMED_CONSULT_LINE = ' • ARMED pre-fold sequence for a bridge-raised finding: the round is open → dispatch that bridge\'s consult with a nonce → WAIT and READ → fold accepted or corrected → flow-writer consult-attestation <planId> --backend <id> --nonce <n> --proposed-fix-digest <the-sha256-of-the-fold-text> → then edit. A lens-raised finding re-dispatches the lens without a nonce, WAIT and READ, then edit as accepted or corrected — it mints no manifest and no attestation — only its per-round participation rides its internal-attestation.';
|
|
238
|
-
//
|
|
239
|
-
//
|
|
240
|
-
//
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
: []),
|
|
260
|
-
]
|
|
261
|
-
: [];
|
|
251
|
+
// The instrument line renders ONLY for plan-execution — its gates judge the commit. A lens-only roster
|
|
252
|
+
// resolves to `solo` and a fully degraded request resolves to `solo`: both still run a review round,
|
|
253
|
+
// which is why the gate never reads the effective recipe alone.
|
|
254
|
+
const reviewLoopAdvice = (slots, activity, flowArmed = false) => {
|
|
255
|
+
if (activity === EPIC) return EPIC_LENS_LINES;
|
|
256
|
+
if (!slots.some((s) => s.roster != null || REVIEW_RECIPES.has(s.recipe) || REVIEW_RECIPES.has(s.degradedFrom))) return [];
|
|
257
|
+
return [
|
|
258
|
+
'Review-loop economics (procedures.md Fold + loop · orchestration.md §4) — the review this recipe runs:',
|
|
259
|
+
CONSULT_LINE,
|
|
260
|
+
...(activity === 'plan-execution' && flowArmed ? [ARMED_CONSULT_LINE] : []),
|
|
261
|
+
CAP_LINE,
|
|
262
|
+
RE_READ_LINE,
|
|
263
|
+
...(activity === 'plan-execution' ? [RE_CHECK_LINE] : []),
|
|
264
|
+
" • Backend divergence (one backend grounded-ships while another keeps revising mechanics) IS the crossover stop: resolving it at altitude is a fold like any other, through the fold ask and its raiser's re-read.",
|
|
265
|
+
' • Route an all-mechanics/CI or prose-only artifact to a thin plan + diff-review; run a self-consistency read before every re-review.',
|
|
266
|
+
" • Each round MUST emit {round N · finding-origin tally (first-draft / fold-induced / mechanics) · per-backend verdict} so the crossover is a computed signal: the verdicts read from the round's receipts and each lens member's answer.",
|
|
267
|
+
...(activity === 'plan-execution'
|
|
268
|
+
? [" • The computed instrument for THIS loop: a code fold is shown red by its test's run before the fix, the run named in the session record; an unavailable backend gets an explicit core-evidence degrade record, never a silent skip; then stage everything, run the reviews on the STAGED tree, and mint the ONE receipt with run-gates --final; the commit is gated by commit-guard --check (the D13 ordering: any edit after the final run re-stales it); read the loop state statelessly with core-evidence summary."]
|
|
269
|
+
: []),
|
|
270
|
+
];
|
|
271
|
+
};
|
|
262
272
|
|
|
263
273
|
// The grounding pre-step (AD-038, extending the AD-033 verbatim-contract rendering): whenever the
|
|
264
274
|
// resolved dispatch includes agy-review, print the CONCRETE facts-assembly invocation + the
|
|
265
275
|
// --facts form as a copy-paste pre-step — population, not placeholders. Plan-path population rule
|
|
266
276
|
// (the review-state plan-in-flight detector): exactly ONE renderable plan in flight → render it
|
|
267
277
|
// populated; zero, several, or a name a one-line render cannot carry → the explicit placeholder + a
|
|
268
|
-
// one-line discovery caveat
|
|
269
|
-
//
|
|
270
|
-
// suggested --out lives OUTSIDE the repo (/tmp) — grounding.mjs refuses a non-scratch destination.
|
|
278
|
+
// one-line discovery caveat. plan-authoring's agy review reads the spec review file, never the plan
|
|
279
|
+
// file alone. The suggested --out lives OUTSIDE the repo (/tmp) — grounding.mjs refuses a non-scratch destination.
|
|
271
280
|
// Exported for the bridge-tier byte-parity pin (AD-044 Plan 4): the velocity tier seeds the
|
|
272
281
|
// grounding rule in EXACTLY this rendered spelling — `node "${GROUNDING_TOOL}"` — so seeded and
|
|
273
282
|
// rendered forms can never drift apart.
|
|
@@ -277,8 +286,8 @@ export const REPO_SEARCH_TOOL = join(dirname(fileURLToPath(import.meta.url)), 'r
|
|
|
277
286
|
export const FEEDBACK_RECORD_TOOL = join(dirname(fileURLToPath(import.meta.url)), 'feedback-record-cli.mjs');
|
|
278
287
|
const FEEDBACK_TRIAGE = 'feedback-triage';
|
|
279
288
|
const EPIC = 'epic';
|
|
289
|
+
const isEpicLensReview = (activity, slot) => activity === EPIC && slot === 'review';
|
|
280
290
|
const GROUNDING_FACTS_OUT = '/tmp/review-facts.md';
|
|
281
|
-
const MINTS_RECEIPT = Object.freeze({ mintsReceipt: true });
|
|
282
291
|
const FEEDBACK_BRIDGE_LINES = Object.freeze({
|
|
283
292
|
'codex-review': 'codex-review plan <record>',
|
|
284
293
|
'agy-review': 'agy-review plan <record> --facts @<facts>',
|
|
@@ -310,35 +319,18 @@ const renderFeedbackTriageAdvice = (activity, slots) => {
|
|
|
310
319
|
];
|
|
311
320
|
};
|
|
312
321
|
|
|
313
|
-
// The round table judges what review-rounds-cli resolves from the config (S27), never
|
|
314
|
-
// override or degradation, so the advisor states that fact beneath the command instead of
|
|
315
|
-
// when the two agree; a bridge-less roster gets the fact that no receipt can exist in the
|
|
316
|
-
// A requested review recipe renders the command even when every bridge is unavailable
|
|
317
|
-
// degradation removes no configured obligation, so the table still has something to say.
|
|
322
|
+
// The feedback-triage round table judges what review-rounds-cli resolves from the config (S27), never
|
|
323
|
+
// this render's override or degradation, so the advisor states that fact beneath the command instead of
|
|
324
|
+
// predicting when the two agree; a bridge-less roster gets the fact that no receipt can exist in the
|
|
325
|
+
// command's place. A requested review recipe renders the command even when every bridge is unavailable
|
|
326
|
+
// here: readiness degradation removes no configured obligation, so the table still has something to say.
|
|
318
327
|
const ROUND_RENDER_FACT_LINE = " ↳ the table judges the obligation review-rounds-cli resolves from docs/ai/orchestration.json (S27) — the configured recipe, or the computed default for a silent slot — never this run's --override or a degraded recipe; it reads receipts only: a backend that did not run shows as missing (no receipts when none ran), and its degrade record is judged by review-state and core-evidence summary, not here.";
|
|
319
328
|
const ROUND_RENDER_NO_BRIDGE_LINE = " • Round render: a roster with no bridge mints no receipt, so review-rounds-cli cannot supply this round's verdicts — emit the finding-origin tally plus each lens member's verdict (or silent) directly.";
|
|
320
|
-
const roundRenderAdvice = (slots, plans) => {
|
|
321
|
-
const review = slots.find((s) => s.slot === 'review');
|
|
322
|
-
if (review === undefined) return [];
|
|
323
|
-
const roster = review.roster ?? null;
|
|
324
|
-
if (!mintsReceipts(review)) return [ROUND_RENDER_NO_BRIDGE_LINE];
|
|
325
|
-
const lensMembers = (roster ?? []).filter((row) => row.kind === 'lens').map((row) => row.member);
|
|
326
|
-
const operand = populatedPlan(plans, MINTS_RECEIPT);
|
|
327
|
-
return [
|
|
328
|
-
` • Round render (verdict half of the per-round emission; the finding-origin tally stays the orchestrator's): node ${renderToolPath(REVIEW_ROUNDS_TOOL)} --artifact ${operand ?? '<plan-file>'}`,
|
|
329
|
-
...planDiscoveryCaveat(plans, '--artifact', 'populate --artifact with the plan file under review.', operand === null ? ['--artifact'] : []),
|
|
330
|
-
ROUND_RENDER_FACT_LINE,
|
|
331
|
-
...(lensMembers.length > 0 ? [` ↳ the table carries the bridge verdicts only — add each lens member's verdict (or silent) by hand: ${lensMembers.join(', ')}`] : []),
|
|
332
|
-
];
|
|
333
|
-
};
|
|
334
329
|
|
|
335
330
|
// The ONE plan in flight as a pasteable operand: shell-significant bytes ride shellQuoteArg; a name a
|
|
336
|
-
// one-line render cannot carry is never populated
|
|
337
|
-
|
|
338
|
-
// round table would match no receipt.
|
|
339
|
-
const populatedPlan = (plans, { mintsReceipt = false } = {}) => {
|
|
331
|
+
// one-line render cannot carry is never populated.
|
|
332
|
+
const populatedPlan = (plans) => {
|
|
340
333
|
if (plans.length !== 1 || !isRenderableLine(plans[0])) return null;
|
|
341
|
-
if (mintsReceipt && !isArtifactPathCarriable(plans[0])) return null;
|
|
342
334
|
return shellQuoteArg(`${PLANS_REL}/${plans[0]}`);
|
|
343
335
|
};
|
|
344
336
|
const planDiscoveryCaveat = (plans, flag, noPlanAction, fellBack = []) => {
|
|
@@ -381,36 +373,23 @@ const groundingPreStepAdvice = (activity, slots, plans) => {
|
|
|
381
373
|
if (activity === FEEDBACK_TRIAGE) return [];
|
|
382
374
|
if (!slots.some((s) => (s.backends ?? []).includes('agy-review'))) return [];
|
|
383
375
|
const operand = populatedPlan(plans);
|
|
384
|
-
|
|
385
|
-
const
|
|
386
|
-
// plan-authoring reviews the plan FILE — a plain name in flight renders the review command populated;
|
|
387
|
-
// the renderability and receipt-carriability fallbacks are the only placeholders a known path produces.
|
|
388
|
-
const reviewForm =
|
|
389
|
-
activity === EPIC
|
|
390
|
-
? 'agy-review plan <brief-file>'
|
|
391
|
-
: activity === 'plan-authoring'
|
|
392
|
-
? reviewOperand === null
|
|
393
|
-
? 'agy-review plan <plan-file>'
|
|
394
|
-
: `agy-review plan ${reviewOperand}`
|
|
395
|
-
: 'agy-review code';
|
|
376
|
+
// The spec review reads the contracts and the plan's ledger in one review file the orchestrator writes.
|
|
377
|
+
const reviewForm = activity === 'plan-authoring' ? 'agy-review plan <spec-review-file>' : 'agy-review code';
|
|
396
378
|
// `run:`/`then:` prefixes keep these POPULATED command lines machine-distinguishable from the
|
|
397
379
|
// verbatim contract DESCRIPTORS above (the descriptor drift guard set-equals bare wrapper lines).
|
|
398
380
|
// The TOOL path stays double-quoted (the bridge tier seeds that exact byte-form); the plan operand
|
|
399
381
|
// rides shellQuoteArg — bare when safe, single-quoted otherwise.
|
|
400
|
-
|
|
382
|
+
return [
|
|
401
383
|
'Grounding pre-step (agy is dispatched — assemble the verified facts BEFORE the review; grounding.mjs slices verbatim, judgment additions stay yours):',
|
|
402
|
-
` run: node "${GROUNDING_TOOL}" --constraints --autonomy${
|
|
384
|
+
` run: node "${GROUNDING_TOOL}" --constraints --autonomy --plan ${operand ?? '<path>'} --out ${GROUNDING_FACTS_OUT}`,
|
|
403
385
|
` then: ${reviewForm} --facts @${GROUNDING_FACTS_OUT}`,
|
|
386
|
+
...planDiscoveryCaveat(
|
|
387
|
+
plans,
|
|
388
|
+
'--plan',
|
|
389
|
+
'substitute the plan file you are reviewing against, or drop --plan for constraints+autonomy facts.',
|
|
390
|
+
operand === null ? ['--plan'] : [],
|
|
391
|
+
),
|
|
404
392
|
];
|
|
405
|
-
if (activity === EPIC) return lines;
|
|
406
|
-
const fellBack = [operand === null ? '--plan' : null, activity === 'plan-authoring' && reviewOperand === null ? 'agy-review plan' : null].filter(Boolean);
|
|
407
|
-
lines.push(...planDiscoveryCaveat(
|
|
408
|
-
plans,
|
|
409
|
-
'--plan',
|
|
410
|
-
'substitute the plan file you are reviewing against, or drop --plan for constraints+autonomy facts.',
|
|
411
|
-
fellBack,
|
|
412
|
-
));
|
|
413
|
-
return lines;
|
|
414
393
|
};
|
|
415
394
|
|
|
416
395
|
// The per-activity autonomy block (AD-044 Plan 4): the resolved level for THIS activity + what it
|
|
@@ -534,7 +513,7 @@ const flowHalvesAdvice = (flow, probe) => {
|
|
|
534
513
|
const chainLine = probe.broken != null
|
|
535
514
|
? ` chain: store BROKEN — ${probe.broken}; every composed checker fails closed on it`
|
|
536
515
|
: !probe.present
|
|
537
|
-
? ' chain: UNARMED — no flow store file yet
|
|
516
|
+
? ' chain: UNARMED — no flow store file yet'
|
|
538
517
|
: probe.armed
|
|
539
518
|
? ' chain: ARMED — the flow store carries an adoption record'
|
|
540
519
|
: ' chain: UNARMED — a store file exists but no chain is adopted (semantic arms stay inert, #52)';
|
|
@@ -629,12 +608,14 @@ const contractLines = ({ cmd, contract, settings }) => {
|
|
|
629
608
|
return lines;
|
|
630
609
|
};
|
|
631
610
|
|
|
632
|
-
|
|
611
|
+
// The fold lane under a delegated execute slot (this activity's, or task.execute under plan-execution):
|
|
612
|
+
// one line resuming the run's session, its id read from the run's exec receipt — no ledger is read.
|
|
613
|
+
const FOLD_LANE_LINE = `Fold lane (execute = delegated) — a fold of code a bridge wrote resumes that run's session: ${wrapperCmdFor('codex-cli-bridge', 'execute')} --resume <session id> --nonce <n> <prompt file>, the session id read from the sessionId of the run's exec receipt, with a new prompt and a fresh nonce; the orchestrator may make the fold itself.`;
|
|
614
|
+
const foldLaneAdvice = ({ activity, slots, config, detection }) => {
|
|
633
615
|
const own = slots.find((slot) => slot.slot === 'execute')?.recipe;
|
|
634
616
|
const task = activity === 'plan-execution' ? resolveActivityRecipe({ config: config ?? {}, readiness: detection, activity: 'task', slot: 'execute' }).recipe : null;
|
|
635
617
|
if (!['plan-execution', 'task'].includes(activity) || ![own, task].includes('delegated')) return [];
|
|
636
|
-
|
|
637
|
-
return foldLaneLines(judgeLedger(ledger, { backend: HELD_RECEIPT_BACKEND, degrades: [] }));
|
|
618
|
+
return [FOLD_LANE_LINE];
|
|
638
619
|
};
|
|
639
620
|
|
|
640
621
|
const formatHuman = ({ activity, section, slots, warnings, plans, autonomy, flowHalves, flowArmed, readersSweep, declaredPractice, foldScope, specCheck, robustnessBrief, foldLane }) => {
|
|
@@ -649,7 +630,7 @@ const formatHuman = ({ activity, section, slots, warnings, plans, autonomy, flow
|
|
|
649
630
|
// A switch slot states what the flag DOES under the effective carrier; both keep the source suffix.
|
|
650
631
|
lines.push(isSwitchSlot(s.slotType)
|
|
651
632
|
? ` ${parallelLine({ value: s.recipe, carrier })} — ${SOURCE_LABEL[s.source]}`
|
|
652
|
-
: ` ${s.slot}: ${s.recipe} — ${SOURCE_LABEL[s.source]}${arrow}${backendSetLabel(s.backends)}`);
|
|
633
|
+
: ` ${s.slot}: ${s.recipe} — ${SOURCE_LABEL[s.source]}${arrow}${backendSetLabel(s.backends, isEpicLensReview(activity, s.slot))}`);
|
|
653
634
|
if (s.reason) lines.push(` ↳ ${s.reason}`);
|
|
654
635
|
if (s.slot === 'review') lines.push(...renderFeedbackTriageAdvice(activity, slots));
|
|
655
636
|
// The form replaces the one-line vehicle mention: a carrier never told how to carry is a name,
|
|
@@ -666,7 +647,7 @@ const formatHuman = ({ activity, section, slots, warnings, plans, autonomy, flow
|
|
|
666
647
|
if (readersSweep.length) lines.push('', ...readersSweep);
|
|
667
648
|
const grounding = groundingPreStepAdvice(activity, slots, plans);
|
|
668
649
|
if (grounding.length) lines.push('', ...grounding);
|
|
669
|
-
const advice = reviewLoopAdvice(slots, activity, flowArmed
|
|
650
|
+
const advice = reviewLoopAdvice(slots, activity, flowArmed);
|
|
670
651
|
if (advice.length) lines.push('', ...advice);
|
|
671
652
|
if (foldScope.length) lines.push('', ...foldScope);
|
|
672
653
|
if (specCheck.length) lines.push('', ...specCheck);
|
|
@@ -691,7 +672,7 @@ const buildJson = ({ activity, section, slots, configSource, warnings, plans, au
|
|
|
691
672
|
...(s.roster ? { roster: s.roster } : {}),
|
|
692
673
|
}]),
|
|
693
674
|
),
|
|
694
|
-
reviewLoop: reviewLoopAdvice(slots, activity, flowArmed
|
|
675
|
+
reviewLoop: reviewLoopAdvice(slots, activity, flowArmed),
|
|
695
676
|
readersSweep,
|
|
696
677
|
// ADDITIVE (AD-038): the populated grounding pre-step, structured (empty when agy is not dispatched).
|
|
697
678
|
groundingPreStep: groundingPreStepAdvice(activity, slots, plans),
|
|
@@ -799,18 +780,7 @@ export const main = (argv, ctx = {}) => {
|
|
|
799
780
|
const foldScope = foldScopeAdvice(activity, config, plans);
|
|
800
781
|
const specCheck = specCheckAdvice(activity);
|
|
801
782
|
const robustnessBrief = robustnessBriefAdvice(activity, plans);
|
|
802
|
-
const foldLane = foldLaneAdvice({
|
|
803
|
-
activity,
|
|
804
|
-
slots,
|
|
805
|
-
config,
|
|
806
|
-
detection,
|
|
807
|
-
cwd,
|
|
808
|
-
env,
|
|
809
|
-
resolveStore: ctx.resolveDelegationStorePath,
|
|
810
|
-
readStore: ctx.readDelegationStore,
|
|
811
|
-
audit: ctx.auditDelegationStoreSemantics,
|
|
812
|
-
readHead: ctx.readHeadInstant,
|
|
813
|
-
});
|
|
783
|
+
const foldLane = foldLaneAdvice({ activity, slots, config, detection });
|
|
814
784
|
const stdout = json
|
|
815
785
|
? JSON.stringify(buildJson({ activity, section, slots, configSource, warnings, plans, autonomy, flowHalves, flowArmed: flowState?.armed === true, readersSweep, declaredPractice, foldScope, specCheck, robustnessBrief, foldLane }), null, 2)
|
|
816
786
|
: formatHuman({ activity, section, slots, warnings, plans, autonomy, flowHalves, flowArmed: flowState?.armed === true, readersSweep, declaredPractice, foldScope, specCheck, robustnessBrief, foldLane });
|
package/tools/rules-regions.mjs
CHANGED
|
@@ -53,6 +53,7 @@ const COMMS_PRIORS = [
|
|
|
53
53
|
];
|
|
54
54
|
const STORY_PRIOR_FIVE_SESSIONS = `### 2.x. Story sessions
|
|
55
55
|
A story — one row of an epic's ledger, carried by one plan — runs as five sessions, each ending at its own review checkpoint: **spec** (the contract under \`docs/ai/specs/\`, drafted and reviewed on the \`plan-authoring\` recipe), **plan** (the ledger, same recipe), **tests** (one task per ledger row, red first), **code** (one task per row, to green), and **diff review, release and record** (the review of the staged tree on the \`plan-execution\` recipe, the release where the story ships one, then the changelog and handover entries and the plan's Phase: Cleanup). Tests and code never share a session, and a spec and its plan never share one either. A storyless plan runs the same five. **Exception — a split:** moving code and its existing cases into modules, with no new logic and no new case, is one session: a short spec (the Module list), the split, the diff review, the release, Cleanup.`;
|
|
56
|
+
const STORY_PRIOR_ONE_TASK = `${STORY_PRIOR_FIVE_SESSIONS} Inside the tests and code sessions it is one task per session: each task runs as its own carrier session — one brief, one run, never one run for a whole wave — and the orchestrator's session briefs, checks, verifies and folds.`;
|
|
56
57
|
|
|
57
58
|
export const RULES_REGIONS = Object.freeze([
|
|
58
59
|
Object.freeze({
|
|
@@ -67,7 +68,7 @@ export const RULES_REGIONS = Object.freeze([
|
|
|
67
68
|
headingRe: /^### 2[.]([0-9]+)[.] Story sessions/,
|
|
68
69
|
label: '### 2.x. Story sessions',
|
|
69
70
|
canon: TEMPLATE_CANON,
|
|
70
|
-
priors: [STORY_PRIOR_FIVE_SESSIONS],
|
|
71
|
+
priors: [STORY_PRIOR_FIVE_SESSIONS, STORY_PRIOR_ONE_TASK],
|
|
71
72
|
}),
|
|
72
73
|
Object.freeze({
|
|
73
74
|
id: 'lens',
|