1231 Commits
Author SHA1 Message Date
haelyra b144908df6 fix(types): declare Git utility options 2026-10-25 19:43:37 -04:00
haelyra 0a7a9a718e fix(hooks): use session repository for console warnings 2026-10-25 19:32:16 -04:00
haelyra 605e006137 Integrate L4XB PR #3662 2026-10-25 19:30:50 -04:00
haelyra 9c8a66b696 Integrate L4XB PR #3664 2026-10-25 19:30:50 -04:00
haelyra 0e7588cec5 Integrate L4XB PR #3667 2026-10-25 19:30:50 -04:00
haelyra 6ddc4ea007 Integrate L4XB PR #3666 2026-10-25 19:30:50 -04:00
haelyra f390400944 Merge pull request #3583 from Tivonsico/fix/skill-run-timestamp-type-20261014
fix(skill-tracker): reject non-string execution timestamps
2026-10-25 19:16:34 -04:00
haelyra 7f0b6ce500 fix(install): reject malformed empty-container JSONC commas 2026-10-25 18:20:40 -04:00
haelyra f4e8f6eb3e Merge reviewed OpenCode JSONC fix from #3590 2026-10-25 18:17:10 -04:00
haelyra e3292b0010 Merge pull request #3594 from ketpatil77/fix/managed-hook-config-bom
fix(hooks): honor managed preferences in BOM-prefixed config
2026-10-25 17:44:47 -04:00
haelyra e494799377 Merge pull request #3654 from affaan-m/stewardship/verified-pr-batch-3569-3578-owned
Integrate 34 reviewed ECC fixes with verified follow-up patches
2026-10-25 15:39:22 -04:00
haelyra 108ff18624 feat(ci): limit Issue bursts and open submissions per author (#3723)
Verified with 30 exact-head hosted checks, 31 combined PR and Issue tests, workflow security validation, and a live read-only Issue replay.
2026-10-25 15:16:53 -04:00
4c28a7be9e ci: audit closed-issue delivery claims — cited PRs must actually be merged (#3522)
* ci: audit closed-issue delivery claims — cited PRs must actually be merged

Follow-up to #3223: an issue closed as 'fixed in #N' while #N was closed
without merging (or does not exist) leaves a completion claim that does not
hold. The weekly maintenance workflow now runs a read-only audit over issues
closed in the last 30 days, extracts delivery-claim PR references from issue
bodies and close-window comments, verifies each cited PR's merge state, and
reports findings to the step summary.

Design constraints:
- Read-only: no comments, no closes, no labels; findings are advisory and
  the run always stays green so the weekly audit never blocks maintenance.
- Unverifiable counts as unmerged: a 404 PR or an API failure fails the
  verdict, because an unverifiable claim is exactly the failure mode.
- Pure decision functions are exported for tests; a first live run against
  this repository surfaced one real finding (#3408 cites #3060, which does
  not resolve), included here as the motivating sample.

8 unit/contract tests: extraction, windowing (close comments included),
the #3223 unmerged-citation failure mode, the all-clear summary, workflow
contract, and a no-write guard.

* ci: rework audit evidence contract — claims vs context, four PR states, visible completeness

Revision per the #3522 review (reviewer ran the CLI through 19 controlled
cases plus a bounded live check of #3408):

- Bind findings to asserted delivery claims. Closing wording ('Delivered
  through #N'), claim verbs (fixed/shipped/landed/resolved/...), and bare
  'PR #N' inside closing comments are claims; historical mentions, quoted
  lines, fenced examples, negated claims, and tracking-only references are
  reported as contextual references and never produce findings. On the live
  #3408 the audit now recognizes the closing claim #3500 (merged) instead of
  flagging the historical #3060 text.
- Separate observed states: merged / open-unmerged / closed-unmerged /
  unknown (404, rate limit, transient). Unknown claims are advisory manual-
  verification items, not failed claims; each row carries the claim snippet,
  its source link, and the observation time. Checked claims are listed even
  when passing, so the report is traceable rather than an opaque all-clear.
- Paginate issue and comment collection (--paginate --slurp), bound comment
  requests (200) and PR checks (100), and surface skipped pages, rate limits,
  and retrieval failures as an explicit incomplete audit instead of an empty
  all-clear. A live-run maxBuffer overflow on the paginated issue list was
  caught and fixed (64MB); the audit reported it as incomplete before the fix.
- Scope the job to read access: job-level contents/issues/pull-requests read.

13 contract/unit tests including a CLI fixture (stub gh) that places the
relevant issue on page two and forces a comment-fetch failure.

* ci: report incomplete audit at PR check cap

---------

Co-authored-by: chenhz01 <chenhz01@users.noreply.github.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-10-25 14:41:22 -04:00
L4XB 10e7c5800f fix(hooks): recognize Prettier's TypeScript and JSON5 config files
Prettier's config searcher also reads .prettierrc.json5, .prettierrc.ts/.mts/.cts and prettier.config.ts/.mts/.cts. resolve-formatter knew none of them, so a project configured only through prettier.config.ts was never formatted by post-edit-format, quality-gate or the Stop batch. config-protection's rc pattern stopped at .yaml/.toml, so an existing .prettierrc.ts or .prettierrc.json5 could be edited freely.
2026-10-22 23:51:32 +02:00
L4XB cd1f5b74e2 fix(hooks): match tsc diagnostics by the file they name
The Stop typecheck reported every tsc line that contained the edited path anywhere. A root index.ts has the relative path `index.ts`, which every `src/index.ts(...)` diagnostic contains, so a clean root file was reported with the errors of src/index.ts. The same happened to src/utils.ts with web/src/utils.ts, and to any file named in another file's message.

Compare the path that starts the diagnostic (`path(line,col): `), keeping the slash normalization for Windows.
2026-10-22 23:42:21 +02:00
L4XB b02e02dcd2 fix(hooks): list modified files from the repository root even with diff.relative
With diff.relative=true, `git diff --name-only` reports paths relative to the working directory, so joining them to the repository root pointed at files that do not exist, and a session in a subdirectory again got no console.log warning. getGitModifiedFiles now runs `git -c diff.relative=false diff --name-only HEAD`. The -c form also works on Git versions older than --no-relative.
2026-10-22 23:01:26 +02:00
L4XB 5311485e94 fix(hooks): keep a backslash in double quotes as bash does in the dev-server block
readToken dropped every backslash inside double quotes, while bash drops it only before $, `, ", \\ or a newline. `"echo ready\;"` therefore reached the tmux check as `echo ready;`, read as a command separator, and `tmux send-keys -t dev "echo ready\;" "npm run dev" Enter` was blocked although it types into a pane.
2026-10-22 22:45:28 +02:00
L4XB adf435d36f fix(hooks): find console.log in modified files from a subdirectory session
check-console-log took the paths from `git diff --name-only HEAD`, which are relative to the repository root, and checked them with fs.existsSync from the hook's working directory. In a session started in a subdirectory, such as a monorepo package, no path existed from there, so the hook never warned. Resolve each path from the repository root. The exclusion patterns and the warning still use the root-relative path.
2026-10-22 22:42:08 +02:00
L4XB eee00776be fix(hooks): end a tmux command at a semicolon that ends an argument
tmux also separates commands at a `;` that ends an argument, so `new-session -d 'npm run dev;' run-shell 'npm run dev'` runs the second dev server without a pane. Split there as well. An escaped `\;` at the end of an argument stays literal, as in tmux.
2026-10-22 22:32:33 +02:00
L4XB 87945aac1f fix(hooks): read tmux option clusters and command sequences in the dev-server block
Two forms got the pane exemption although they run the dev server without a pane.

`tmux -vL new-session run-shell ...`: in a cluster, the last option that takes a value (f, L, S, T) takes the next token, here the socket name `new-session`. A `c` anywhere in a cluster (`-c'npm run dev'`) runs a shell command without a pane.

`tmux new-session -d \; run-shell "npm run dev"`: only the first command of a sequence was checked. The sequence is now split at `;`, and it is exempt only when every command in it that runs the dev server is a pane command. This also closes the same hole for the plain `tmux new-session ... \; run-shell`, which the old regex exempted.
2026-10-22 21:59:23 +02:00
L4XB 99aa85dde9 fix(hooks): let the dev-server block see a tmux launch past tmux options
The block allowed a dev server only when the segment began with `tmux new`, `new-session`, `new-window` or `split-window`. It therefore blocked dev servers that do start in a tmux pane, the way its own message asks: `tmux -L work new-session ...` and `tmux -f conf new-session ...` (tmux options before the command), `/opt/homebrew/bin/tmux new-session ...` and `env TERM=... tmux new-session ...`, the aliases `neww` and `splitw`, and `tmux send-keys -t dev 'npm run dev' Enter` or `respawn-pane` for a session that exists.

Read the tmux command from the parsed segment instead, after the leading command word and tmux's own options, and allow the commands that run their shell command in a pane. `tmux run-shell` and `tmux -c` run it without one and stay blocked.
2026-10-22 21:15:25 +02:00
haelyra 6e11d21dd1 Merge branch 'stewardship/verified-pr-batch-3538-3566' into stewardship/verified-pr-batch-3602-3621-owned 2026-10-20 18:41:32 -04:00
haelyra a6db53f835 fix(inspection): normalize diagnostic-looking Windows filenames 2026-10-20 18:41:19 -04:00
haelyra fcff074e6f Merge branch 'stewardship/verified-pr-batch-3538-3566' into stewardship/verified-pr-batch-3602-3621-owned 2026-10-20 18:28:33 -04:00
haelyra c04d00c15e fix(integration): address review findings in docs and diagnostics 2026-10-20 18:17:37 -04:00
Eneko Ruiz 21e0ab5271 fix(session-aliases): reject array-shaped alias maps
(cherry picked from commit b1668579f6)
2026-10-20 17:40:59 -04:00
Eneko Ruiz 0bdb6a52ab fix: validate session alias titles before saving
(cherry picked from commit e4f9aac414)
2026-10-20 17:40:58 -04:00
Alan Vo 67034687f3 Fix CLAUDE_CONFIG_DIR tilde expansion, blank path fallback, and inline WSL resolver parity
(cherry picked from commit 617ab29f8d)
2026-10-20 17:40:58 -04:00
Alan Vo 5701a4f2e1 fix: respect CLAUDE_CONFIG_DIR with WSL Windows-path conversion
(cherry picked from commit aaacbc7592)
2026-10-20 17:40:58 -04:00
Eneko Ruiz f1c6692f99 fix: include the oldest dashboard window boundary
(cherry picked from commit e32d1a4e4d)
2026-10-20 17:40:58 -04:00
Eneko Ruiz 65f7dfb735 fix: reject missing session database and limit values
(cherry picked from commit 299899941d)
2026-10-20 17:40:57 -04:00
Eneko Ruiz 8f72869987 fix: reject negative execution counters
(cherry picked from commit fed9eebed5)
2026-10-20 17:40:57 -04:00
Eneko Ruiz 3ac640f6cc fix: sort missing inspection dates after pre-epoch timestamps
(cherry picked from commit 774dfd6894)
2026-10-20 17:40:57 -04:00
Eneko Ruiz c2a28b2963 fix: order failure pattern timestamps chronologically
(cherry picked from commit 075d55e9cb)
2026-10-20 17:40:57 -04:00
haelyra 14693070a1 fix: normalize apostrophes inside quoted Windows paths
(cherry picked from commit 8ab9358e18)
2026-10-20 17:38:38 -04:00
Eneko Ruiz c73353e2c7 fix: normalize Windows backup filename suffixes
(cherry picked from commit f685582ebe)
2026-10-20 17:38:38 -04:00
Eneko Ruiz 9388e06ec7 fix: preserve diagnostics after extensionless Windows paths
(cherry picked from commit 2a2e6e3848)
2026-10-20 17:38:38 -04:00
Eneko Ruiz 58b191c25d fix: normalize trailing Windows paths and spaced filenames
(cherry picked from commit c31b1dd80c)
2026-10-20 17:38:38 -04:00
Eneko Ruiz 0931f66775 fix: normalize Windows paths containing spaces and Unicode
(cherry picked from commit 25b775edc1)
2026-10-20 17:38:37 -04:00
Eneko Ruiz 9824f422d2 fix: normalize Windows file paths in failure patterns
(cherry picked from commit e0de4739a9)
2026-10-20 17:38:37 -04:00
Eneko Ruiz 5367671a22 fix: reject missing session inspection option values
(cherry picked from commit a6619f5efd)
2026-10-20 17:38:13 -04:00
30b68924ae fix(install): treat .pi as a foreign platform path (#3560)
The platform-configs module lists `.pi`, but PLATFORM_SOURCE_PATH_OWNERS
had no entry for it, so isForeignPlatformPath() returned false and every
install-apply target (e.g. `--target opencode`) copied the Pi harness
adapter (.pi/README.md, .pi/extensions/*) into its config root and
recorded it as ECC-managed.

Pi consumes ECC through `pi install`, not install-apply, so map `.pi` to
the `pi` owner. No install target has that id, so the directory is now
filtered out everywhere, like `.codex`, `.cursor`, and `.zed`.

Add regression tests for the opencode plan and for every registered
target.

Fixes #3558

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: haelyra <49814733+haelyra@users.noreply.github.com>
2026-10-20 15:37:53 -04:00
haelyra 224f99c059 Merge branch 'main' into fix/managed-hook-config-bom 2026-10-20 15:18:22 -04:00
haelyra a31dfbf0e4 Merge branch 'main' into fix/jsonc-opencode-config-membership-check 2026-10-20 15:18:17 -04:00
Affaan Mustafa 6f1881aeaf refactor(lib): split nasiko install, uninstall and tar extraction
extractQualifiedTarGzip walked the archive, validated the terminator, read each header and classified the entry in one loop; installNasiko and uninstallNasiko each resolved the release and paths, then ran the whole download or staging sequence inside one try with rollback flags. The extractor now uses gunzipArchive, assertTarTerminator, readTarEntry, isBinaryEntry and isSidecarEntry. The two lifecycle calls share qualifiedReleaseFor and installPathsFor; install fetches through fetchVerifiedBinary and publishes through publishBinary, and uninstall stages and deletes through removeInstalledFiles with removeOrRetain.

The rollback rules are the same: a failed publish removes only the files this call created, a failed rename puts the staged file back, and a failed delete keeps the tombstone and reports it in cleanupPending. The plan still takes its version from the requested release, not from releaseOverride, and every dependency hook is called in the same order. Exports are unchanged, and a run of the old and new extractor over 20k generated archives covering sidecars, bad padding, bad size fields, truncation and trailing data produced identical results and messages.
2026-10-19 23:39:18 -04:00
Affaan Mustafa 5c507e0704 refactor(lib): split search evidence by tool and credit path
searchEvidence built the Glob, Grep and LS evidence inline before falling through to the shell path, and findCreditingSearch and findClosestMiss each nested the per-search and per-item loops with the stem and directory checks in one body. The tool builders are now globEvidence, grepEvidence and lsEvidence behind a small Map, the item loop of findCreditingSearch is creditingItem, and findClosestMiss hands the miss reasons to missReason and the Read scan to considerReads. searchHasMessage replaces the repeated messageId check.

Results are unchanged: the same first crediting search wins, the same lowest-ranked miss is reported, and errors still resolve to null inside the two public functions. Checked by running the old and new factory side by side over 40k generated scans and targets with identical output.
2026-10-19 23:39:18 -04:00
Affaan Mustafa 87aaef56cb refactor(lib): split the gateguard code lexer by token class
lexCodeLines ran every state (code, line comment, block comment, string) through one loop body with three closures over its locals, and shCodeLines and psCodeLines each inlined their escape, quote and comment readers. The C-family lexer now keeps its partial line on a small lx record and dispatches by state to lexNewline, lexLineComment, lexBlockComment, lexString and lexCode, with lexCommentStart, startsJsx and lexStringStart under lexCode. The shell lexers share pushShellLine, readEscapedPair, readQuotedSpan and readLineComment; shCodeLines looks its readers up in a table and psCodeLines splits into psBlockComment and psToken.

Every reader returns the index of the last character it consumed, so the loops advance exactly as before, and the sentinel for an unlexable edit is still null from the C-family path and a null result from the shell paths. Exports are unchanged. A differential run against the previous version over the unit test strings plus 40k generated inputs, across all nine spec shapes change-profile builds, produced identical lines, normalized signatures and isTrivialEdit verdicts.
2026-10-19 23:39:18 -04:00
Affaan Mustafa 26d2010a16 refactor(hooks): split shell-scan into per-token helpers
heredocDelimiter, executionRegion and scanShell each carried one long character loop with every quote, escape, heredoc, case and scope rule inline, which is where the three complexity warnings came from. The delimiter reader now has skipDelimiterBlanks, delimiterEscape and readDelimiterWord; the $(...) walker dispatches to regionQuotedEnd, regionSubstitution, openRegionQuote, regionHeredocOperator, regionHeredocBodies, casePhaseStep and closeRegionParen; and the top-level scanner keeps its position and pending word on a scan object that scanQuotedChar, scanEscape, scanSubstitution, openQuote, scanOperator and scanRedirect advance.

Every budget.spend call keeps its amount and order, so the work quota tests still land in the same window. The module still has no requires and exports createBudget, scanShell and scanExpansions unchanged; a differential run of the old and new scanner over the hook test corpus plus 58k generated inputs produced identical commands, nested regions and spend totals.
2026-10-19 23:39:18 -04:00
Affaan Mustafa d53359a974 refactor(scripts): table-drive the operator readiness dashboard
parseArgs now reads flags from two lookup tables, one for flags that take a
value in either form and one for standalone switches, instead of thirty-odd
if blocks. The ECC Tools evidence and gap text live in ordered tier tables
keyed by roadmap markers, with the shared marker lists named once.
buildRequirements reads its docs and readiness checks up front, then
assembles the list from four requirement groups. The PR and issue budget
rows share one builder.

Flag errors, requirement order, and every message string are unchanged.
Verified by comparing parseArgs over a flag matrix and buildReport over the
repo, an empty root, and one synthetic roadmap per marker. Clears the four
complexity warnings on this file.
2026-10-19 22:18:32 -04:00
Affaan Mustafa 905bb16ff2 refactor(lib): split gateguard file-context scanners by token
cFamilyStartsFresh ran one 130-line loop over template literals, comments,
regex-vs-division, C# and Rust raw strings, quotes, words, and punctuation.
It now keeps scanner state in one object and walks a fixed list of step
functions, each returning consumed, abort, or not-mine. The Python f-string
field scan, the shell heredoc and quote tokens, and the PowerShell
here-string, block comment, and hash tokens get the same treatment.

Verified byte-for-byte against the recorded test inputs, four hundred real
source files from the repo, random prefixes, and single-character mutations
across every flavor spec. Clears the five complexity warnings on this file.
2026-10-19 22:18:32 -04:00