@dev-loops/core 1.0.1 → 1.0.2-slim.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.
@@ -123,7 +123,7 @@ register(INTERNAL_DEV_LOOP_STRATEGY.FINAL_APPROVAL, "default", {
123
123
  register(INTERNAL_DEV_LOOP_STRATEGY.LOCAL_IMPLEMENTATION, "default", {
124
124
  criteria: [
125
125
  { id: "phase-ac", must: "All phase acceptance criteria from the active phase doc are satisfied.", severity: "required" },
126
- { id: "verify-green", must: "`npm run verify` passes with no failures.", severity: "required" },
126
+ { id: "verify-green", must: "`bun run verify` passes with no failures.", severity: "required" },
127
127
  ],
128
128
  evidence: ["commands-run", "validation-output", "changed-files"],
129
129
  maxFinalizationTurns: 6,
@@ -131,14 +131,14 @@ register(INTERNAL_DEV_LOOP_STRATEGY.LOCAL_IMPLEMENTATION, "default", {
131
131
  activeNoticeAfterMs: DEFAULT_ACTIVE_NOTICE_MS,
132
132
  });
133
133
 
134
- // local_implementation · spike run (SPIKE-RELAXED-GATE-PROFILE, #1628): a
134
+ // local_implementation · spike run (SPIKE-RELAXED-GATE-PROFILE): a
135
135
  // spike-mode spin resolves the relaxed `spike` gate profile instead of the
136
136
  // default local-implementation gate. Kept as its own acceptance key so the
137
137
  // generic default can stay approach-agnostic.
138
138
  register(INTERNAL_DEV_LOOP_STRATEGY.LOCAL_IMPLEMENTATION, "spike", {
139
139
  criteria: [
140
140
  { id: "spike-recorded", must: "The spike exploration and its recommendation are recorded (spike file + summary).", severity: "required" },
141
- { id: "verify-green", must: "`npm run verify` passes with no failures.", severity: "required" },
141
+ { id: "verify-green", must: "`bun run verify` passes with no failures.", severity: "required" },
142
142
  ],
143
143
  evidence: ["commands-run", "validation-output", "changed-files"],
144
144
  maxFinalizationTurns: 6,
@@ -305,7 +305,7 @@ function deriveRequiredReads(bundle, resolverOutput) {
305
305
  }
306
306
 
307
307
  // ---------------------------------------------------------------------------
308
- // specSource derivation (issue #1025 — lightweight PR-body-as-spec)
308
+ // specSource derivation — lightweight PR-body-as-spec
309
309
  // ---------------------------------------------------------------------------
310
310
 
311
311
  /**
@@ -440,7 +440,7 @@ function deriveCwd(bundle, options = {}) {
440
440
  }
441
441
 
442
442
  /** Repo-relative root for loop-owned worktrees. The `dev-loops/` namespace */
443
- /** marks them so cleanup can only ever remove its own (issue #909). */
443
+ /** marks them so cleanup can only ever remove its own. */
444
444
  export const WORKTREE_NAMESPACE = "tmp/worktrees/dev-loops";
445
445
 
446
446
  /**
@@ -470,7 +470,7 @@ function flattenSlugSegment(s) {
470
470
  }
471
471
 
472
472
  function buildWorktreeSlug(artifact, kind) {
473
- // Canonical naming is namespaced + no branch suffix (issue #909) so the path
473
+ // Canonical naming is namespaced + no branch suffix so the path
474
474
  // is recomputable from the issue/PR number alone (cleanup can find it).
475
475
  if (kind === DEV_LOOP_TARGET_KIND.ISSUE && Number.isInteger(artifact.issue) && artifact.issue > 0) {
476
476
  return `issue-${artifact.issue}`;
@@ -511,7 +511,7 @@ function normalizeGateState(gateState) {
511
511
 
512
512
 
513
513
  /**
514
- * Normalize the structured retrospective findings (issue #1077, Reading B).
514
+ * Normalize the structured retrospective findings.
515
515
  *
516
516
  * The retrospective is advisory: it never blocks merge or any lifecycle
517
517
  * transition. Its findings travel in the handoff envelope (the conductor's
@@ -553,7 +553,7 @@ function resolveSubGate(strategy, gateState) {
553
553
  return "default";
554
554
  }
555
555
 
556
- /** True when the resolver output identifies a spike-mode run (#1628). */
556
+ /** True when the resolver output identifies a spike-mode run. */
557
557
  function isSpikeRun(resolverOutput) {
558
558
  return Boolean(resolverOutput && resolverOutput.spikeIntakeState);
559
559
  }
@@ -593,7 +593,7 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
593
593
  if (!repo) throw new Error("handoff-envelope: repo slug is required (owner/name)");
594
594
 
595
595
  const gs = normalizeGateState(gateState);
596
- // SPIKE-RELAXED-GATE-PROFILE (#1628): a spike-mode spin (startup resolver
596
+ // SPIKE-RELAXED-GATE-PROFILE: a spike-mode spin (startup resolver
597
597
  // result carrying `spikeIntakeState`) resolves the relaxed `spike` gate
598
598
  // profile instead of the default local-implementation gate. The spike
599
599
  // marker lives at the TOP level of the resolver output (the bundle does not
@@ -603,7 +603,7 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
603
603
  : resolveSubGate(strategy, gs);
604
604
  // Normalize each source independently, then fall back on the normalized result
605
605
  // (not the raw value): a present-but-invalid gateState value must NOT shadow a
606
- // valid options.retrospectiveFindings fallback (issue #1077 review finding).
606
+ // valid options.retrospectiveFindings fallback.
607
607
  const retrospectiveFindings = normalizeRetrospectiveFindings(gateState?.retrospectiveFindings)
608
608
  ?? normalizeRetrospectiveFindings(options.retrospectiveFindings);
609
609
 
@@ -613,7 +613,7 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
613
613
  const gateConfig = deriveGateConfig(settings, subGate);
614
614
  const derivedCwd = deriveCwd(bundle, { repoRoot: options.repoRoot, worktreeCwd: options.worktreeCwd });
615
615
  const template = lookupAcceptanceTemplate(strategy, subGate);
616
- // Lightweight PR-body-as-spec (issue #1025): retarget the phase-doc criterion
616
+ // Lightweight PR-body-as-spec: retarget the phase-doc criterion
617
617
  // text to the PR description. Null/phase_doc leaves the criteria untouched, so
618
618
  // the non-lightweight path stays byte-identical.
619
619
  const specSource = deriveSpecSource(bundle, resolverOutput);
@@ -623,7 +623,7 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
623
623
  ? { ...options.overrides }
624
624
  : undefined;
625
625
 
626
- // Sanctioned operation → wrapper command map (issue #1081). Core is
626
+ // Sanctioned operation → wrapper command map. Core is
627
627
  // consumer-agnostic: it carries whatever map the consumer supplies (the
628
628
  // `loop build-envelope` CLI injects this repo's scripts/... paths) so every
629
629
  // spawned subagent receives it by DEFAULT. Core defines the SHAPE only —
@@ -632,7 +632,7 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
632
632
  ? options.sanctionedCommands
633
633
  : undefined;
634
634
 
635
- // Surface the *effective* async-start posture alongside the *configured* one (#834). The
635
+ // Surface the *effective* async-start posture alongside the *configured* one. The
636
636
  // configured `asyncStartMode` is echoed verbatim from settings (back-compat), but the contract
637
637
  // is relaxed at validation time under the Claude harness (resolveEffectiveAsyncStartMode →
638
638
  // "allowed" when CLAUDECODE=1). Without surfacing the effective value, a `required` envelope
@@ -686,21 +686,21 @@ export function buildDevLoopHandoffEnvelope(resolverOutput, settings, gateState
686
686
  envelope.sanctionedCommands = sanctionedCommands;
687
687
  }
688
688
 
689
- // Advisory retrospective findings (issue #1077, Reading B). Optional structured
689
+ // Advisory retrospective findings. Optional structured
690
690
  // field carrying the check-retro-tooling.mjs JSON output to the conductor. Never a
691
691
  // gate — the conductor surfaces these as an advisory PR comment, not a block.
692
692
  if (retrospectiveFindings) {
693
693
  envelope.retrospectiveFindings = retrospectiveFindings;
694
694
  }
695
695
 
696
- // Canonical spec source (issue #1025). Optional: only set when the resolver
696
+ // Canonical spec source. Optional: only set when the resolver
697
697
  // marks a lightweight PR-body-as-spec session, so the default (phase-doc) path
698
698
  // carries no specSource field and its envelope stays byte-identical.
699
699
  if (specSource) {
700
700
  envelope.specSource = specSource;
701
701
  }
702
702
 
703
- // #1462: the ONLY per-round-varying block, kept LAST. Every field here changes
703
+ // The ONLY per-round-varying block, kept LAST. Every field here changes
704
704
  // between builds/rounds (the timestamp, the head SHA, CI status, thread/round
705
705
  // counts); isolating them as the envelope's tail keeps everything above a
706
706
  // byte-stable prefix that a fresh reviewer spawn can cache-READ instead of
@@ -931,7 +931,7 @@ export function validateHandoffEnvelope(envelope) {
931
931
  });
932
932
  }
933
933
 
934
- // ----- asyncStartEffective (required field; the harness-resolved posture, #834) -----
934
+ // ----- asyncStartEffective (required field; the harness-resolved posture) -----
935
935
  if (envelope.asyncStartEffective === undefined || envelope.asyncStartEffective === null) {
936
936
  errors.push({
937
937
  field: "asyncStartEffective",
@@ -946,7 +946,7 @@ export function validateHandoffEnvelope(envelope) {
946
946
  });
947
947
  }
948
948
 
949
- // ----- retrospectiveFindings (optional, advisory — issue #1077) -----
949
+ // ----- retrospectiveFindings (optional, advisory) -----
950
950
  if (envelope.retrospectiveFindings !== undefined && envelope.retrospectiveFindings !== null) {
951
951
  const rf = envelope.retrospectiveFindings;
952
952
  if (typeof rf !== "object" || Array.isArray(rf)) {
@@ -968,7 +968,7 @@ export function validateHandoffEnvelope(envelope) {
968
968
  }
969
969
  }
970
970
 
971
- // ----- specSource (optional — issue #1025, lightweight PR-body-as-spec) -----
971
+ // ----- specSource (optional — lightweight PR-body-as-spec) -----
972
972
  if (envelope.specSource !== undefined && envelope.specSource !== null) {
973
973
  const validSources = [CANONICAL_SPEC_SOURCE.PHASE_DOC, CANONICAL_SPEC_SOURCE.PR_BODY];
974
974
  if (typeof envelope.specSource !== "string" || !validSources.includes(envelope.specSource)) {
@@ -980,8 +980,8 @@ export function validateHandoffEnvelope(envelope) {
980
980
  }
981
981
  }
982
982
 
983
- // ----- gateState.derivedAt (informational, warn on missing) — #1462 moved the
984
- // volatile timestamp into the gateState tail so the rest stays byte-stable -----
983
+ // ----- gateState.derivedAt (informational, warn on missing) — the
984
+ // volatile timestamp lives in the gateState tail so the rest stays byte-stable -----
985
985
  if (typeof envelope.gateState?.derivedAt !== "string" || !envelope.gateState.derivedAt.trim()) {
986
986
  warnings.push({ field: "gateState.derivedAt", reason: "should be an ISO 8601 timestamp" });
987
987
  }