Commit Graph

958 Commits

Author SHA1 Message Date
haelyra
1bdda4bdac fix: close validator and path edge cases 2026-08-29 15:36:59 -04:00
haelyra
703163275d test: honor per-invocation Bash overrides 2026-08-29 15:11:38 -04:00
haelyra
224da03d01 fix(gateguard): match heredoc tab-strip order 2026-08-29 14:55:14 -04:00
haelyra
fab534f924 test(hooks): keep matcher mirrors in sync 2026-08-29 14:55:14 -04:00
wellkilo
a4d72b2271 fix(gateguard): surface graduated recovery hints
Change-Id: I6ade0a2a54a26bd5721c62edf7efa462e8043a08
Co-authored-by: TRAE CLI <traecli@bytedance.com>
2026-08-29 14:55:14 -04:00
dajiaohuang
c40d0e4f7c fix: normalize heredoc line continuations 2026-08-29 14:55:14 -04:00
dajiaohuang
9768c075c3 refactor: keep heredoc scanning linear 2026-08-29 14:55:14 -04:00
dajiaohuang
e72191ba74 fix: harden heredoc command filtering 2026-08-29 14:55:14 -04:00
dajiaohuang
962380c452 fix: ignore heredoc prose in GateGuard 2026-08-29 14:55:14 -04:00
Suliman Abdulrazzaq
6fa3efeef7 fix(hooks): use valid wildcard matchers 2026-08-29 14:55:14 -04:00
haelyra
30c41a9bde fix: close truth and portability review gaps 2026-08-29 14:55:14 -04:00
haelyra
9542c33454 test(skill-stocktake): cover canonical symlink discovery
Co-authored-by: LKL-ZREO <891878708@qq.com>
2026-08-29 14:55:13 -04:00
Juan Pablo
974ccc749f fix(ci): validate SKILL.md frontmatter under docs/{locale}/skills/ mirrors
Extends scripts/ci/validate-skills.js to also scan docs/{locale}/skills/
translated mirrors, not just curated skills/. Adds detection for the
YAML defect classes from #2630 without a parser dependency: unquoted
values containing ": " (glued next key / dropped quoting), values
starting with the reserved '@'/'`' indicators, and missing frontmatter
blocks entirely (required only for docs mirrors; curated skills/ keeps
its existing tolerant behavior).
2026-08-29 14:55:13 -04:00
Souptik Chakraborty
51dc76ee07 test(gateguard): reject Reflect access on process.env
Greptile flagged that the env-access guard in
gateguard-env-documented.test.js could be bypassed via reflective reads
of process.env (Reflect.get/has/set/deleteProperty/defineProperty/
getOwnPropertyDescriptor/ownKeys), since none of the existing
UNSUPPORTED_ACCESS patterns matched that form.

Add a rule that rejects Reflect.get/has/set/deleteProperty/
defineProperty/getOwnPropertyDescriptor/ownKeys(process.env, ...) and
three self-check fixture cases (Reflect.get, Reflect.has,
Reflect.ownKeys) so the guard is pinned against silently missing them
again.

Negative control: commenting out only the new rule reproduces exactly
the reported gap (the 3 new fixture cases fail with "access guard
missed: Reflect.get, Reflect.has, Reflect.ownKeys"); restoring it goes
back to 10/10.
2026-08-29 14:55:13 -04:00
Souptik Chakraborty
f1521c8937 test(gateguard): read env knobs from code and pin the access convention
The documentation surface test scanned the hook's raw source with two
regexes. That had two holes, both confirmed against the shipped parser:

- a GATEGUARD_* name appearing only in a comment or a string was counted
  as a real read, and
- destructured, aliased and computed reads were invisible, so an
  undocumented knob added in one of those forms would pass silently.

Blank comments, string literals, template-literal text and regex literals
before scanning, so only real code contributes. Blanking preserves length,
so `process.env[...]` keys are located in the blanked code and read back
from the raw source at the same offset.

Rather than chase every possible access form with regexes, the supported
forms are now enforced: destructuring, aliasing, spreading, enumerating
and computed keys fail the guard with instructions to either keep the
convention or extend the parser. Six self-checks cover the blanker and
the guard, including a regex literal containing a slash.

Refs #2573
2026-08-29 14:55:13 -04:00
Souptik Chakraborty
c4253805b5 docs(gateguard): address review - split full-disable, pin glob semantics
CodeRabbit review on #2611, all four findings:

- GATEGUARD_DISABLED sat in a table introduced as 'these do not disable the gate'. Moved to its own full-disable section with ECC_GATEGUARD, and corrected the accepted values against ECC_DISABLE_VALUES (0/false/off/disabled/disable - the earlier draft would have implied 'no' works, which it does not).

- Documented that a leading **/ compiles to .*/ and so needs a preceding separator: verified by reproducing the hook's glob->regex translation, **/tests/** matches /repo/tests/foo.js but not a bare relative tests/foo.js. Docs now say so and the example carries both forms. Matcher behaviour deliberately unchanged - widening it is a behaviour change, not a docs fix.

- Reverse-drift check now compares documented names against the parsed env reads instead of hookSource.includes(), so a name surviving only in a comment or error string no longer satisfies it.

- readGateguardEnvNames builds one Set from collected matches instead of mutating via Set#add, per the repo's no-in-place-mutation guideline.
2026-08-29 14:55:13 -04:00
Souptik Chakraborty
4377ea1753 docs(gateguard): document the graduated gate controls
GateGuard reads five GATEGUARD_* environment variables that were absent
from skills/gateguard/SKILL.md, so the only discoverable escape hatch was
ECC_GATEGUARD=off - disabling the load-bearing destructive-Bash gate
along with the noisy ones (#2573).

Documented, with defaults and exact accepted values read from the hook:

- GATEGUARD_BASH_ROUTINE_DISABLED (was undocumented everywhere)
- GATEGUARD_EXEMPT_GLOBS (previously only in a 2.1.0 release note)
- GATEGUARD_BASH_EXTRA_DESTRUCTIVE (was undocumented)
- GATEGUARD_DISABLED (was undocumented)
- GATEGUARD_STATE_DIR (was undocumented; named in a runtime warning)
- GATEGUARD_FACT_FORCE_FULL_DENIALS (already documented; folded into the
  same table for one lookup point)

Adds tests/ci/gateguard-env-documented.test.js, which asserts every
GATEGUARD_* variable the hook reads appears in the skill doc, and that the
doc names no variable the hook has stopped reading. That surface test is
what found the three knobs beyond the two the issue reported.

Docs and test only; no hook behaviour changes.

Refs #2573
2026-08-29 14:55:13 -04:00
haelyra
2f8a5a271d test: cover inferred-window hook output 2026-08-29 14:55:13 -04:00
Tanel
ecdd517765 fix(suggest-compact): don't quote a percentage against an assumed window
The context signal always rendered "N% of <window> window", including when
the window size was the assumed 200k default rather than a detected value.
On a 1M session whose transcript carries no [1m] marker, that produced
lines like:

  [StrategicCompact] Context ~194k tokens (97% of 200k window)

while actual usage was ~19%. The user compacts on a false alarm, loses
context, and the resulting quality drop reads as a model regression.

The gap is structural: the context threshold defaults to 80% of the
window (160k on 200k), so the signal fires precisely in the 160k-200k
band where the size cannot be determined — above 200k the observed-tokens
fallback correctly infers 1M, and below 160k nothing fires.

Model id alone cannot close this. A tier may ship both a 200k and a 1M
variant under one id, so neither the known-family table nor a new entry
can distinguish them, and the transcript records no window field.

So stop asserting what isn't known: resolveContextWindow() now reports
whether the size was detected (env override, [1m] marker, known family,
or observed tokens > 200k) or assumed, and the hook omits the percentage
and window label when it was assumed. The token count, threshold, and
firing behaviour are unchanged.

resolveContextWindowTokens() keeps its existing signature and semantics.

Note: 3 pre-existing failures in tests/hooks/suggest-compact.test.js
reproduce identically on unmodified main and are untouched here.
2026-08-29 14:55:13 -04:00
haelyra
e82e477034 test(pack): tolerate slow Windows extraction 2026-08-29 14:53:54 -04:00
haelyra
4c7e965209 fix(gan): distinguish scores from verdict thresholds 2026-08-29 14:24:16 -04:00
van3hardy
b2a8091440 test(opencode): guard plugin.tool existence before shape assertion 2026-08-29 13:40:57 -04:00
van3hardy
e72f1e6824 test(opencode): assert init does not call shell and root plugin tools 2026-08-29 13:40:56 -04:00
van3hardy
f932e63b0a test(opencode): assert built entry is a working plugin, not just an export shape 2026-08-29 13:40:56 -04:00
van3hardy
f0684fda32 test(opencode): assert built entry exports only the plugin function 2026-08-29 13:40:56 -04:00
曹博淳
fcef85cb87 test: skip GAN shell checks on Windows 2026-08-29 13:40:56 -04:00
haelyra
cce8f60206 test(gan): use portable Bash lookup on Windows 2026-08-29 13:40:56 -04:00
CaoBochun
91e846dfe2 test: execute final GAN score selection 2026-08-29 13:40:56 -04:00
CaoBochun
8a396ef542 test: strengthen GAN harness assertions 2026-08-29 13:40:56 -04:00
CaoBochun
37e9683161 test: address GAN harness review feedback 2026-08-29 13:40:56 -04:00
CaoBochun
70eb0f68ae fix: make GAN harness score parsing portable 2026-08-29 13:40:56 -04:00
haelyra
73c29bbd08 fix(install): register AdaL capability metadata 2026-08-29 13:40:56 -04:00
Haoran Zhang
1e7493595c fix(adal): correct README install paths and add adapter regression tests
Address CodeRabbit review feedback on PR #2607:
- Fix .adal/README.md to document actual install paths (rules/, skills/)
  instead of the incorrect namespaced rules/ecc/, skills/ecc/ paths.
- Add regression tests for the adal-project install target adapter:
  root/install-state path resolution, dual id/target registry lookup,
  native .adal root sync-root-children behavior, and foreign platform
  path filtering.

Co-Authored-By: AdaL <adal@sylph.ai>
2026-08-29 13:40:56 -04:00
benno0o
7c2bc54be2 test: verify Corepack uses the pinned pnpm version 2026-08-29 13:40:56 -04:00
benno0o
b48f22f08c fix: address pre-push pnpm review findings 2026-08-29 13:40:53 -04:00
benno0o
03b441792e fix: resolve pnpm in Git Bash pre-push hook 2026-08-29 13:40:53 -04:00
haelyra
656d4b5746 Merge pull request #2869 from actus7/consolidate/mcp-health-v3
fix(hooks): consolidate MCP health-check fixes (3 PRs)
2026-08-29 00:22:27 -04:00
haelyra
303f50c57e test(hooks): construct mismatch prefix immutably 2026-08-28 22:43:28 -04:00
haelyra
b2ab65d0fb fix(hooks): classify platform-dependent raw prefixes 2026-08-28 22:35:23 -04:00
haelyra
d5ebac49b1 Merge pull request #2380 from chs0813/fix/plugin-hook-bootstrap-no-echo
fix(hooks): do not echo raw input from plugin-hook-bootstrap.js
2026-08-28 22:24:24 -04:00
haelyra
9ff6949798 Merge pull request #2351 from vladyslavTezyk/main
Add ukranian translation of the main Readme.
2026-08-28 21:59:45 -04:00
haelyra
13c476965f fix(hooks): keep MCP reachability probes bounded
Remove the redundant JSON-RPC initialize fallback from the consolidated MCP health-check batch. A routed 404 already proves the endpoint is reachable, and the real authenticated MCP call remains authoritative. Avoiding the fallback also prevents a stalled GET plus stalled POST from consuming twice the configured hook timeout.
2026-08-28 21:09:35 -04:00
haelyra
3702a617db Merge remote-tracking branch 'origin/main' into maint/pr-2866-current 2026-08-28 18:29:35 -04:00
haelyra
2aebdd3408 Merge pull request #2870 from actus7/consolidate/hooks-observer-v3
fix(hooks): consolidate hooks and observer fixes (5 PRs)
2026-08-28 18:29:03 -04:00
haelyra
1d19789c75 fix(hooks): preserve metadata-marked human prompts 2026-08-28 16:28:12 -04:00
haelyra
77c358dd3f fix(costs): retain dated Opus 4 legacy pricing 2026-08-28 16:26:13 -04:00
haelyra
70f42102fc test(evolve): support Windows line endings 2026-08-28 16:25:30 -04:00
Santhi Prakash
64f0acf60e test: split Sonnet model pricing cases 2026-08-28 16:23:25 -04:00
Santhi Prakash
ab8cbf6505 test: cover Sonnet 5 cache rate splits 2026-08-28 16:23:25 -04:00
Santhi Prakash
616716f370 test: isolate cost tracker cache fixtures 2026-08-28 16:23:25 -04:00