instar 1.3.881 → 1.3.882

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "instar",
3
- "version": "1.3.881",
3
+ "version": "1.3.882",
4
4
  "description": "Coherence infrastructure for self-evolving AI agents — on the Claude Code or Codex subscription you already have.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -337,8 +337,11 @@ if (traceEntries.length === 0) {
337
337
  }
338
338
 
339
339
  // ─── Step 4.5: read the agent's DECLARED tier + branch ───────────────────
340
- // The agent records its tier in the trace JSON. We peek the freshest fresh
341
- // trace to read `trace.tier` (1|2|3). decideRequirementSet() factors the pure
340
+ // The agent records its tier in the trace JSON. Select the freshest trace that
341
+ // actually covers THIS staged change before reading its identity or tier. A
342
+ // merely-newer trace from another worktree/task must never label this decision
343
+ // audit (the feedback-class failure behind fb-2b24aa04-540).
344
+ // decideRequirementSet() factors the pure
342
345
  // enforcement decision:
343
346
  // - tier 1 → 'tier1-lite' (ELI16 + side-effects staged; no spec)
344
347
  // - tier 2 / 3 → 'tier2-full' (the EXISTING full validation, unchanged)
@@ -347,8 +350,28 @@ if (traceEntries.length === 0) {
347
350
  let declaredTier = null;
348
351
  let tierReasoning = '';
349
352
  let freshestTrace = null;
353
+ let freshestTraceEntry = null;
354
+ for (const entry of traceEntries) {
355
+ try {
356
+ const candidate = JSON.parse(fs.readFileSync(entry.file, 'utf8'));
357
+ const covered = new Set(candidate?.coveredFiles || []);
358
+ if (candidate?.phase === 'complete' && inScopeFiles.every((f) => covered.has(f))) {
359
+ freshestTrace = candidate;
360
+ freshestTraceEntry = entry;
361
+ break;
362
+ }
363
+ } catch {
364
+ // The full validation path below reports malformed attempts. They are not
365
+ // eligible to provide identity/tier metadata for this staged change.
366
+ }
367
+ }
368
+ if (!freshestTrace || !freshestTraceEntry) {
369
+ blockCommit(
370
+ inScopeFiles,
371
+ 'No fresh complete trace covers this staged change. Run the /instar-dev skill for the files being committed.',
372
+ );
373
+ }
350
374
  try {
351
- freshestTrace = JSON.parse(fs.readFileSync(traceEntries[0].file, 'utf8'));
352
375
  if (freshestTrace && (freshestTrace.tier === 1 || freshestTrace.tier === 2 || freshestTrace.tier === 3)) {
353
376
  declaredTier = freshestTrace.tier;
354
377
  }
@@ -360,7 +383,13 @@ try {
360
383
  // path (the existing Step 5 loop will surface the malformed-JSON attempt).
361
384
  }
362
385
 
363
- const slug = (freshestTrace && (freshestTrace.slug || freshestTrace.name)) || 'unknown';
386
+ const slug = (freshestTrace && (
387
+ freshestTrace.slug ||
388
+ freshestTrace.name ||
389
+ (typeof freshestTrace.artifactPath === 'string'
390
+ ? path.basename(freshestTrace.artifactPath, path.extname(freshestTrace.artifactPath))
391
+ : null)
392
+ )) || 'unknown';
364
393
  const decision = decideRequirementSet(declaredTier);
365
394
 
366
395
  // ─── Step 4.55: causal autopsy (directive 2026-06-05) ───────────────────
@@ -480,7 +509,7 @@ if (belowFloor) {
480
509
  // (The tests/lint requirement from the spec lives in the pre-PUSH gate, not
481
510
  // here: this pre-COMMIT hook checks ARTIFACTS only.)
482
511
  if (decision.requirementSet === 'tier1-lite') {
483
- enforceTier1(freshestTrace, traceEntries[0].file);
512
+ enforceTier1(freshestTrace, freshestTraceEntry.file);
484
513
  // enforceTier1 either passes through (process.exit(0)) or blockCommit()s.
485
514
  }
486
515
 
@@ -212,6 +212,9 @@ const duplicateBuildCheck = readDuplicateBuildCheck();
212
212
 
213
213
  const trace = {
214
214
  version: toolchain ? 3 : 2, // v3 only when enriched; readers ignore unknown fields either way
215
+ // Stable work-item identity. The pre-commit decision audit consumes this;
216
+ // omitting it forced valid generated traces into the `unknown` bucket.
217
+ slug,
215
218
  sessionId: process.env.INSTAR_SESSION_ID || process.env.CLAUDE_CODE_SESSION_ID || 'unknown',
216
219
  timestamp,
217
220
  artifactPath: artifact,
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "$schema": "./builtin-manifest.schema.json",
3
3
  "schemaVersion": 1,
4
- "generatedAt": "2026-07-19T13:38:17.474Z",
5
- "instarVersion": "1.3.881",
4
+ "generatedAt": "2026-07-19T21:04:24.400Z",
5
+ "instarVersion": "1.3.882",
6
6
  "entryCount": 202,
7
7
  "entries": {
8
8
  "hook:session-start": {
@@ -0,0 +1,24 @@
1
+ # Upgrade Guide — vNEXT
2
+
3
+ <!-- assembled-by: assemble-next-md -->
4
+ <!-- bump: patch -->
5
+
6
+ ## What Changed
7
+
8
+ - Persisted stable work-item identity in generated Instar development traces.
9
+ - Bound decision evidence to the staged change's matching trace before reading identity or tier, with a compatibility fallback for legacy traces.
10
+ - Added regressions for missing generated identity and a newer foreign `unknown` trace competing with the correct trace.
11
+
12
+ ## What to Tell Your User
13
+
14
+ None — internal change (no user-facing surface).
15
+
16
+ ## Summary of New Capabilities
17
+
18
+ None — internal change (no user-facing surface).
19
+
20
+ ## Evidence
21
+
22
+ - Feedback: `fb-2b24aa04-540`
23
+ - Test: `tests/unit/instar-dev-precommit-audit-staging.test.ts`
24
+ - Test: `tests/unit/write-trace-tier.test.ts`
@@ -0,0 +1,9 @@
1
+ # Decision audit trace binding
2
+
3
+ Instar records a small decision artifact whenever its own development gate evaluates a change. That artifact is supposed to answer a simple future question: which work item was this decision about, and what change did the gate actually evaluate? The gate previously answered that question using the newest trace file written in the last hour. In a busy development environment, however, the newest trace can belong to another task or another attempted commit. That let a real change be recorded under `unknown` or under a foreign work-item name even though a correct trace for the staged files was present.
4
+
5
+ This repair changes the binding rule for the whole class, not just the reported instance. The canonical trace writer now persists the stable slug it already derives from the side-effects artifact. Before the gate reads a trace's tier, slug, or causal record, it requires that trace to be complete and to cover every staged behavior file. Newer unrelated or malformed traces are skipped. For older generated traces that predate the slug field, the gate derives the same stable identity from `artifactPath`. If no trace covers the staged change, the commit is refused with a direct explanation instead of emitting misleading evidence.
6
+
7
+ The important invariant is: development evidence is selected by scope first and recency second. A regression test creates two fresh traces—an older correct trace and a newer foreign `unknown` trace—and proves that the resulting decision record uses the correct work-item identity. This closes feedback item `fb-2b24aa04-540` and upgrades the development process so parallel work cannot recreate the same evidence-misbinding class.
8
+
9
+ There is no runtime or user-facing behavior change. The affected surface is the Instar source repository's pre-commit ceremony. Rollback is a normal code revert; no persisted runtime state or migration is involved.
@@ -0,0 +1,72 @@
1
+ # Side-Effects Review — decision audit trace binding
2
+
3
+ **Version / slug:** `decision-audit-trace-binding`
4
+ **Date:** `2026-07-19`
5
+ **Author:** `Instar Agent (instar-codey)`
6
+ **Second-pass reviewer:** `not required`
7
+
8
+ ## Summary of the change
9
+
10
+ The trace writer now persists its derived slug, and the pre-commit gate selects the newest complete trace whose `coveredFiles` includes every staged behavior file before reading tier, slug, or class evidence. Legacy traces fall back to their artifact basename. Regression tests pin both causes from `fb-2b24aa04-540`: missing generated identity and a newer foreign trace.
11
+
12
+ ## Decision-point inventory
13
+
14
+ - `scripts/instar-dev-precommit.js` trace selection — modified — deterministically binds evidence to the staged change and refuses when no binding exists.
15
+
16
+ ## 1. Over-block
17
+
18
+ A legacy hand-written trace without `phase: complete` or without complete behavior-file coverage is now refused earlier. That is intentional: such a trace cannot honestly describe the staged decision.
19
+
20
+ ## 2. Under-block
21
+
22
+ Two traces can both cover the same files; recency remains the tie-breaker. The trace SHA and artifact checks still validate the selected trace later in the gate.
23
+
24
+ ## 3. Level-of-abstraction fit
25
+
26
+ The repair spans the canonical trace producer and the pre-commit evidence binder. It persists the already-derived artifact slug and reuses the existing `coveredFiles` contract instead of introducing another identity system.
27
+
28
+ ## 4. Signal vs authority compliance
29
+
30
+ [docs/signal-vs-authority.md](../../docs/signal-vs-authority.md) applies. This is an enumerable integrity invariant: evidence either covers all staged behavior files or it does not. The deterministic gate correctly holds blocking authority over an invalid development commit.
31
+
32
+ ## 4b. Judgment-point check
33
+
34
+ No competing-signals judgment is introduced. Scope membership is an exact set-containment invariant.
35
+
36
+ ## 5. Interactions
37
+
38
+ The selector runs before Tier-1 branching and before the existing full trace validation. It cannot double-fire. Full artifact, SHA, and spec validation remain unchanged. Parallel worktrees may leave traces behind, but those traces no longer influence unrelated staged changes.
39
+
40
+ ## 6. External surfaces
41
+
42
+ No runtime, user, operator, network, or API surface changes. The persistent decision audit becomes more accurate.
43
+
44
+ ## 6b. Operator-surface quality
45
+
46
+ No operator surface — not applicable.
47
+
48
+ ## 7. Multi-machine posture
49
+
50
+ Machine-local by design: pre-commit traces and staged changes belong to one development worktree on one machine. It emits no user notice, creates no transferable runtime state, and generates no URL.
51
+
52
+ ## 8. Rollback cost
53
+
54
+ Pure development-tooling code change. Revert and ship; no migration or agent-state repair is required.
55
+
56
+ ## Conclusion
57
+
58
+ The class review found the missing standard was scope-bound evidence selection, and the process gap was reading identity from the newest trace before proving it described the staged files. The code and regression ratchet now enforce scope-first, recency-second selection. Clear to ship.
59
+
60
+ ## Second-pass review
61
+
62
+ Not required: this does not touch runtime messaging, sessions, sentinels, guards, or watchdogs.
63
+
64
+ ## Evidence pointers
65
+
66
+ - `tests/unit/instar-dev-precommit-audit-staging.test.ts`
67
+ - `tests/unit/write-trace-tier.test.ts`
68
+ - Feedback `fb-2b24aa04-540`
69
+
70
+ ## Class-Closure Declaration (display-only mirror)
71
+
72
+ `defectClass: claim-vs-evidence`, `closure: guard`, `guardEvidence: { enforcementType: gate, citation: scripts/instar-dev-precommit.js#freshestTraceEntry, howCaught: the gate selects only a complete trace covering every staged behavior file before using its slug or tier, so a newer foreign or unknown trace cannot label the decision }`.