Repository navigation
Commit 07e3674
release: v0.9.6 (#1129)
* release: v0.9.6
Correctness release for `check --checks *` + native bridge resilience.
Changelog:
- altimate-core 0.7.0 upgrade + consumer contract sync surfaces findings
many `check --checks {validate,semantic,grade,pii,migration,safety,
policy,compare}` paths previously missed. Teams gating CI on `--fail-on
error|warning` may see new failures on unchanged SQL — these are real
findings, not regressions in your code. (#1090)
- Truncated tool-output files were being deleted the moment they were
written since 2026-08-14, due to a 48-bit Identifier timestamp wrap.
Both cleanups now age files by mtime; stat failures fail safe (keep
the file). (#1113, closes #1112)
- Native bridge no longer poisons itself for the process lifetime on a
transient NAPI load failure — registration now caches an in-flight
promise, cleared on failure so subsequent calls can retry. Fix +
adversarial tests from the v0.9.6 release review (Chaos Gremlin).
Deferred to follow-up issues: #1124 (grace-window flag), #1125 (rule
catalog docs), #1126 (legacy-shape-fallback removal), #1127 (NAPI-load-
failure CI job), #1128 (truncate.ts/truncation.ts consolidation).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* release: v0.9.6 review — dispatcher race guard + qualify `rule` wording
Addresses coderabbit findings on the release PR:
- **Major** — dispatcher.ts: without generation tracking, a stale
registration attempt's `.then` handler could clobber replacement state
installed mid-flight by a concurrent `reset()` or `setRegistrationHook()`.
Success path nulled `_ensureRegistered` (wiping a replacement hook);
failure path nulled `_registrationPromise` (breaking dedup for a newer
in-flight promise). Fix: bump a generation counter on every mutation
entry point; the settle handlers only mutate cached state if their
captured generation is still current. 2 new adversarial tests cover
both races.
- **Minor** — CHANGELOG.md and docs/docs/usage/check.md: the "every
finding carries a `rule` field" claim isn't quite true — `lint`
findings may omit `rule` if the engine didn't attach one (matches the
documented Finding Object where `rule` is optional). Qualified the
wording in both files to "when set" / "when the underlying engine
attaches one" so users know to check for presence before switching
on it.
Local verification: `bun test test/skill/release-v0.9.6-adversarial.test.ts
test/altimate/dispatcher.test.ts` → 14/14 pass (2 new race tests).
`bun turbo typecheck` clean.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* release: v0.9.6 review round 2 — self-heal dispatcher after stale register()
Addresses second round of coderabbit + cubic findings on release/v0.9.6:
- **cubic P2 (dispatcher.ts)** — the previous generation guard prevented a
stale hook's `.then` handler from mutating shared state, but the old
hook BODY itself could still `Dispatcher.register()` late and clobber
fresh entries a newer hook had already written. Fix: on stale-generation
success, clear `_registrationPromise` so the next `Dispatcher.call`
re-runs the CURRENT hook — its `register()` calls then idempotently
overwrite whatever the stale hook wrote. Successful current-generation
attempts keep the resolved promise memoized so subsequent calls
fast-path through an already-settled await.
- **cubic P3 (test file)** — replaced every `setTimeout` sync point with
Promise-gate synchronisation. Bun's `async` function bodies run sync
until the first `await`, so `Dispatcher.call(...)` has already registered
its cached promise and hit `await _registrationPromise` by the time
control returns to us — no external delay needed. Tests are now
scheduler-independent.
- **cubic P3 (docs/usage/check.md)** — rewrote the dangling
"and how the rule inventory is discovered in practice" clause. Now
links to the Finding Object schema and calls out which check types
always vs sometimes include `rule`.
- New adversarial test covering the stale-register self-heal path;
full dispatcher suite: 15/15 pass. Non-vacuous: verified the new
test FAILS if the P2 fix is reverted.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* release: v0.9.6 review round 3 — revert P2 self-heal; document contract
Reverts the round-2 self-heal (was: on stale-generation success, clear
`_registrationPromise` so the current hook re-runs). Coderabbit + cubic
both correctly flagged that this reintroduces the very race the round-1
generation guard was meant to prevent: if the stale hook resolves while
a REPLACEMENT hook is still in flight, clearing `_registrationPromise`
clobbers the newer attempt's cached promise — a third caller then starts
a second registration attempt, breaking dedup.
Every attempt to self-heal without inventing a heavier per-entry
generation scheme (or wrapping ``register()`` with a generation guard)
introduces another race. Doing that here would materially complicate
the dispatcher for a scenario that never occurs in production —
``setRegistrationHook`` is called exactly once at startup by
``native/index.ts``, and ``reset()`` is test-only. Test-authored races
that violate isolation are the caller's contract, not this module's
correctness problem.
- Revert to round-1 logic (generation guard on shared-state mutations only)
- Remove the "stale hook self-heal" adversarial test — it was locking in
behavior we've decided not to guarantee
- Add explicit contract documentation to `dispatcher.ts` and to the
adversarial test file's top docstring so the design decision is
discoverable to reviewers next time
Dispatcher suite: 14/14 pass (was 15 with the deleted self-heal test).
The round-1 generation guard is retained and still tested.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* release: v0.9.6 review round 4 — clarify dispatcher concurrency contract
cubic P3 catch: my round-3 wording "reset()/setRegistrationHook() MUST
NOT be called while a call is in flight" is contradicted by this same
PR's adversarial tests — which do exactly that on purpose, to exercise
the generation guard on the .then handlers. The wording was too broad.
Rewrote to distinguish two claims:
• What IS guaranteed: shared-state mutation (`_ensureRegistered` /
`_registrationPromise`) by a stale attempt's .then handler is
blocked by the generation guard. Concurrent reset/setRegistrationHook
is safe wrt that.
• What is NOT: late `Dispatcher.register(...)` calls from a stale
hook BODY (that resumes after replacement) overwrite whatever the
newer hook wrote. No self-heal — chased twice, recreated the
guard's race both times.
• Why: production never triggers late-write clobber (hook set once
at startup, reset() test-only).
Wording-only. No code change.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* release: v0.9.6 review round 5 — CHANGELOG + test-isolation fixes
Addresses three cubic P2 findings on release/v0.9.6:
- **CHANGELOG L10 + bullet (e)/(f)**: my theme + bullets listed
`migration` and `compare` as valid `check --checks` lanes. They are not
— `VALID_CHECKS` in `check-helpers.ts` only accepts
{lint, validate, safety, policy, pii, semantic, grade}. The migration
and compare correctness fixes belong to the `altimate-core-migration`
and `altimate-core-compare` TOOLS (agent tools, not check lanes).
Moved them to their own bullets and dropped them from the check-lane
list in the theme.
- **Test env-var teardown**: `afterAll` unconditionally deleted
`ALTIMATE_TELEMETRY_DISABLED`, wiping any pre-existing value an outer
suite may have set. Now captures the prior value in `beforeAll` and
restores it (or deletes if none was set).
- **Concurrent-failure test coverage**: added a companion to the
concurrent-success test that fires 20 concurrent calls against a
rejecting hook and asserts every one rejects with the SAME error
instance (proving dedup held across the failure path) with the hook
body having run exactly once.
15/15 dispatcher tests pass (14 prior + 1 new).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Haider <haider@altimate.ai>
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>1 parent e27aeac commit 07e3674
4 files changed
Lines changed: 330 additions & 4 deletions
File tree
- docs/docs/usage
- packages/opencode
- src/altimate/native
- test/skill
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
8 | 26 | | |
9 | 27 | | |
10 | 28 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
50 | 50 | | |
51 | 51 | | |
52 | 52 | | |
| 53 | + | |
| 54 | + | |
53 | 55 | | |
54 | 56 | | |
55 | 57 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
20 | 20 | | |
21 | 21 | | |
22 | 22 | | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
23 | 35 | | |
24 | 36 | | |
25 | 37 | | |
26 | 38 | | |
| 39 | + | |
| 40 | + | |
27 | 41 | | |
28 | 42 | | |
29 | 43 | | |
30 | 44 | | |
31 | 45 | | |
| 46 | + | |
| 47 | + | |
32 | 48 | | |
33 | 49 | | |
34 | 50 | | |
35 | 51 | | |
36 | 52 | | |
37 | 53 | | |
38 | 54 | | |
39 | | - | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
40 | 81 | | |
41 | | - | |
42 | | - | |
43 | | - | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
44 | 101 | | |
45 | 102 | | |
46 | 103 | | |
| |||
0 commit comments