instar 1.3.925 → 1.3.926
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/core/time-claim.d.ts.map +1 -1
- package/dist/core/time-claim.js +17 -2
- package/dist/core/time-claim.js.map +1 -1
- package/package.json +1 -1
- package/src/data/builtin-manifest.json +2 -2
- package/upgrades/1.3.926.md +40 -0
- package/upgrades/side-effects/time-claim-parenthetical-anchor.md +70 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-claim.d.ts","sourceRoot":"","sources":["../../src/core/time-claim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IAC1C,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;
|
|
1
|
+
{"version":3,"file":"time-claim.d.ts","sourceRoot":"","sources":["../../src/core/time-claim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,+EAA+E;AAC/E,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAC;IACvB,6EAA6E;IAC7E,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,iCAAiC;IACjC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,SAAS,GAAG,WAAW,GAAG,SAAS,CAAC;IAC1C,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;CACd;AA4ED,8EAA8E;AAC9E,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,EAAE,CA4BhE;AAaD;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAC1C,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,aAAa,CAAC,cAAc,CAAC,GACpC,eAAe,CAuCjB"}
|
package/dist/core/time-claim.js
CHANGED
|
@@ -28,12 +28,27 @@ import { humanizeDuration } from './SessionClock.js';
|
|
|
28
28
|
// Anchored claim patterns. Each requires the anchor WORD so plain durations
|
|
29
29
|
// never match. Hours may be fractional ("7.5 hours"); "Xh Ym" composes.
|
|
30
30
|
// "in" as an elapsed anchor is only accepted at a boundary ("7.5 hours in:",
|
|
31
|
-
// "1h50m in.", "2h in)") — never "3h in CI" /
|
|
31
|
+
// "1h50m in.", "2h in)", "40 min in (iteration 1)") — never "3h in CI" /
|
|
32
|
+
// "in 2 hours".
|
|
33
|
+
//
|
|
34
|
+
// The OPENING paren is in the boundary set deliberately (2026-07-23). It was
|
|
35
|
+
// missing while the CLOSING paren was present, so "40 min in." was recognised
|
|
36
|
+
// and "40 min in (iteration 1)" was not — and a parenthetical annotation after
|
|
37
|
+
// a progress figure is an extremely natural way to write one. That gap let two
|
|
38
|
+
// real fabricated elapsed-time claims through on a live autonomous run: the
|
|
39
|
+
// claims extracted to NOTHING, so the comparison never ran at all.
|
|
40
|
+
//
|
|
41
|
+
// A residual ambiguity is accepted knowingly: "2h in (CI queue)" reads as a
|
|
42
|
+
// PLACE rather than a duration and will now be treated as an elapsed claim. The
|
|
43
|
+
// trade is deliberate — this signal is ADVISORY (it returns the message to the
|
|
44
|
+
// author with a note, it never blocks), so a false positive costs one re-read
|
|
45
|
+
// while a false negative costs the operator a fabricated time report. Tonight
|
|
46
|
+
// supplied the evidence for which way that asymmetry points.
|
|
32
47
|
const HOURS = String.raw `(\d{1,3}(?:\.\d+)?)\s*h(?:ours?|rs?)?`;
|
|
33
48
|
const MINUTES = String.raw `(\d{1,2})\s*m(?:in(?:ute)?s?)?`;
|
|
34
49
|
const HM = `${HOURS}(?:\\s*${MINUTES})?|${MINUTES}`;
|
|
35
50
|
const PRE = String.raw `(?:~|≈|about\s+|around\s+|roughly\s+)?`;
|
|
36
|
-
const ELAPSED_RE = new RegExp(`${PRE}(?:${HM})\\s*(?:elapsed|into\\s+the\\s+(?:run|session)|in(?=\\s*(?:[,.;:)\\]!\\n—–-]|$|now\\b)))`, 'gi');
|
|
51
|
+
const ELAPSED_RE = new RegExp(`${PRE}(?:${HM})\\s*(?:elapsed|into\\s+the\\s+(?:run|session)|in(?=\\s*(?:[,.;:()\\[\\]!\\n—–-]|$|now\\b)))`, 'gi');
|
|
37
52
|
const REMAINING_RE = new RegExp(`${PRE}(?:${HM})\\s*(?:remaining|left|to\\s+go|on\\s+the\\s+clock)`, 'gi');
|
|
38
53
|
// Percent anchors require an explicit TIME noun ("of the run", "through the
|
|
39
54
|
// session") — never bare "complete"/"done"/"through"/"in", which dominantly
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"time-claim.js","sourceRoot":"","sources":["../../src/core/time-claim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAyBrD,4EAA4E;AAC5E,wEAAwE;AACxE,6EAA6E;AAC7E,
|
|
1
|
+
{"version":3,"file":"time-claim.js","sourceRoot":"","sources":["../../src/core/time-claim.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "./builtin-manifest.schema.json",
|
|
3
3
|
"schemaVersion": 1,
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"instarVersion": "1.3.
|
|
4
|
+
"generatedAt": "2026-07-24T01:09:02.453Z",
|
|
5
|
+
"instarVersion": "1.3.926",
|
|
6
6
|
"entryCount": 202,
|
|
7
7
|
"entries": {
|
|
8
8
|
"hook:session-start": {
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Upgrade Guide — vNEXT
|
|
2
|
+
|
|
3
|
+
<!-- assembled-by: assemble-next-md -->
|
|
4
|
+
<!-- bump: patch -->
|
|
5
|
+
|
|
6
|
+
## What Changed
|
|
7
|
+
|
|
8
|
+
The TIME_CLAIM outbound advisory now recognises an elapsed-time claim followed by a parenthetical — `40 min in (iteration 1)` — which it previously did not.
|
|
9
|
+
|
|
10
|
+
The `in` anchor accepted a closing paren as a boundary but not an opening one, so `40 min in.` was checked against the live session clock and `40 min in (iteration 1)` extracted nothing at all, meaning no comparison ran.
|
|
11
|
+
|
|
12
|
+
## What to Tell Your User
|
|
13
|
+
|
|
14
|
+
Nothing to do. The check that verifies my elapsed-time claims against the real clock had a blind spot for one very common way of writing a progress line, and it's closed.
|
|
15
|
+
|
|
16
|
+
## Summary of New Capabilities
|
|
17
|
+
|
|
18
|
+
- Elapsed claims written with a trailing parenthetical or bracket annotation are now verified against the live session clock instead of silently skipped.
|
|
19
|
+
|
|
20
|
+
## Evidence
|
|
21
|
+
|
|
22
|
+
Found by testing the live preflight endpoint against messages actually sent during an active autonomous run.
|
|
23
|
+
|
|
24
|
+
**Before:**
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
POST /messaging/preflight "AUTONOMOUS PROGRESS — 57 minutes elapsed, 7h02m left"
|
|
28
|
+
-> {"advisories":[{"code":"TIME_CLAIM","match":"claimed \"57 minutes elapsed\"; live clock: 3h 58m elapsed", ...}]}
|
|
29
|
+
|
|
30
|
+
POST /messaging/preflight "AUTONOMOUS PROGRESS — 40 min in (iteration 1)"
|
|
31
|
+
-> {"advisories":[]}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Same endpoint, same active clock, same kind of claim — one caught, one invisible.
|
|
35
|
+
|
|
36
|
+
**Root cause:** the `in` anchor's boundary set contained `)` but not `(`. The parenthetical form extracted zero claims, so the clock comparison never executed.
|
|
37
|
+
|
|
38
|
+
**After:** both forms extract and flag. Against a 14-minute clock, `40 min in (iteration 1)` now returns `claimed "40 min in"; live clock: 14m elapsed`.
|
|
39
|
+
|
|
40
|
+
**Not changed:** the 15-minute absolute tolerance floor, which let a separate 57-vs-45-minute claim pass. That is working as designed; narrowing it carries real false-positive cost and is recorded rather than changed.
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# Side-effects review — TIME_CLAIM accepts a following parenthetical
|
|
2
|
+
|
|
3
|
+
**Change:** one character class in `ELAPSED_RE`. The `in` elapsed anchor now
|
|
4
|
+
accepts a following `(` or `[` as a boundary, alongside the existing
|
|
5
|
+
`, . ; : ) ] ! — – -` / end-of-string / `now`.
|
|
6
|
+
|
|
7
|
+
## Why — it missed two real fabrications on a live run
|
|
8
|
+
|
|
9
|
+
Found 2026-07-23 by testing the LIVE `/messaging/preflight` endpoint against
|
|
10
|
+
messages I had actually sent during an active time-boxed autonomous run.
|
|
11
|
+
|
|
12
|
+
The anchor accepted a CLOSING paren but not an OPENING one:
|
|
13
|
+
|
|
14
|
+
| text | before | after |
|
|
15
|
+
|---|---|---|
|
|
16
|
+
| `40 min in.` | extracts, flags | unchanged |
|
|
17
|
+
| `2h in)` | extracts, flags | unchanged |
|
|
18
|
+
| `40 min in (iteration 1)` | **extracts nothing** | extracts, flags |
|
|
19
|
+
| `1h10m in (iteration 1)` | **extracts nothing** | extracts, flags |
|
|
20
|
+
|
|
21
|
+
Both fabricated claims I sent used the parenthetical form — because annotating a
|
|
22
|
+
progress figure with `(iteration N)` is the natural way to write one. The claims
|
|
23
|
+
extracted to **nothing**, so the comparison against the live clock never ran at
|
|
24
|
+
all. Verified against the real endpoint: the same text with a period returns a
|
|
25
|
+
correct `TIME_CLAIM` advisory; with ` (` it returns `advisories: []`.
|
|
26
|
+
|
|
27
|
+
**Not a broken guard.** The wiring is correct and live — the dev-agent gate
|
|
28
|
+
resolves on, the relay posts `topicId` + kind, and conversational sends are
|
|
29
|
+
covered as the one deliberate non-automated exception. Only the boundary set was
|
|
30
|
+
incomplete.
|
|
31
|
+
|
|
32
|
+
## Deliberately NOT changed
|
|
33
|
+
|
|
34
|
+
**The 15-minute absolute tolerance floor.** My other fabricated claim — 57 minutes
|
|
35
|
+
when the truth was 45 — passed because a 12-minute error is inside
|
|
36
|
+
`DURATION_TOLERANCE_FLOOR_S`. That is working as designed (it stops the detector
|
|
37
|
+
nagging about rounding), and narrowing it is a judgment call with real
|
|
38
|
+
false-positive cost, so it is left alone and recorded instead. Worth knowing as a
|
|
39
|
+
property: early in a run the fixed floor covers a proportionally large range — at
|
|
40
|
+
14 minutes elapsed, any claim from 0 to 29 minutes passes.
|
|
41
|
+
|
|
42
|
+
## Risk analysis
|
|
43
|
+
|
|
44
|
+
**The accepted residual:** `2h in (CI queue)` reads as a PLACE and will now be
|
|
45
|
+
treated as an elapsed claim. Knowingly accepted. The signal is **advisory** — it
|
|
46
|
+
returns the message to the author with a note and never blocks — so a false
|
|
47
|
+
positive costs one re-read, while a false negative costs the operator a fabricated
|
|
48
|
+
time report. This session supplied direct evidence for which way that asymmetry
|
|
49
|
+
points.
|
|
50
|
+
|
|
51
|
+
**The boundary rule's purpose is preserved.** `in` followed by a WORD is still not
|
|
52
|
+
an anchor. Negative tests pin `3h in CI`, `in 2 hours`, `spent 2h in review`, and
|
|
53
|
+
the task-progress case `the migration is 80% done` — the widening must not reopen
|
|
54
|
+
any of those, and it doesn't.
|
|
55
|
+
|
|
56
|
+
**Blast radius:** one regex in one pure module. No authority (advisory only), no
|
|
57
|
+
write path, no config key, no schema, no migration surface. Fail-open behaviour on
|
|
58
|
+
every error path is untouched.
|
|
59
|
+
|
|
60
|
+
## Testing
|
|
61
|
+
|
|
62
|
+
`tests/unit/time-claim.test.ts` — 19 green (was 16). New: the two verbatim
|
|
63
|
+
fabricated messages are caught against a 14-minute clock; the square-bracket form;
|
|
64
|
+
all four previously-working boundaries unchanged; and four negatives pinning that
|
|
65
|
+
`in`-before-a-word is still rejected. Full advisory suite set: 41 green.
|
|
66
|
+
`tsc --noEmit` clean.
|
|
67
|
+
|
|
68
|
+
## Rollback
|
|
69
|
+
|
|
70
|
+
Revert. The anchor returns to its previous boundary set.
|