Commit Graph
3948 Commits
Author SHA1 Message Date
Affaan MustafaandAffaan 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 MustafaandAffaan 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
Affaan MustafaandAffaan Mustafa 1e787f62f5 refactor(lib): split install-lifecycle repair and inspect paths
executeRepairOperation, executeUninstallOperation, and inspectManagedOperation
now dispatch on operation kind to one small function per kind, with the
repeated uninstall result shapes and previous-content restore pulled into
helpers. executeRepairOperation takes an options object instead of four
trailing positionals. analyzeRecord is a sequence of collect* steps, and the
per-record repair closure inside repairInstalledStates hands off to
runRecordRepair with the legacy OpenCode, build-only dry run, and managed
repair paths as separate functions.

Result objects keep the same keys in the same order, and lock, build, and
require ordering is unchanged. Clears the max-params and complexity warnings
on this file.
2026-10-19 22:18:32 -04:00
Affaan MustafaandAffaan Mustafa 3849426a95 refactor(ci): share the catalog count replacer
Six summary-line replacers in catalog.js each took seven to nine positional
capture groups and rebuilt the line by hand. They now go through one
catalogCountReplacer factory that takes the regex group count and the groups
holding the agents, skills, and commands counts. Every other group is written
back verbatim.

Output is byte-identical across the real docs and several synthetic catalogs.
Clears the six max-params warnings on this file.
2026-10-19 22:18:32 -04:00
Affaan MustafaandAffaan Mustafa 8c1925722c refactor(lib): split powershell destructive-command scanners
The here-string normalizer, comment stripper, and balanced-group reader each
carried their own copy of the same inert-region state machine. They now share
createLexState, consumeInertChar, and openInertRegion. The container
extractor, statement tokenizer, nested pwsh scanner, cmd scanner, Start-Process
scanner, and top-level statement walk are split into small named helpers that
each handle one region or one command family.

No classification change. Verified against the recorded test inputs plus
mutated variants with an order-sensitive comparison of findings. Clears the
eleven complexity and prefer-const warnings on this file.
2026-10-19 22:18:32 -04:00
Affaan MustafaandAffaan Mustafa 944ea9d050 fix(ci): unescape node -e inline programs in one pass
validateInlineJs unescaped the shell body with four chained replaces,
so a backslash pair followed by n or t was unescaped twice: the pair
became one backslash, then the new backslash-n became a newline. A
valid hook command such as console.log('\\n') failed validation with
an unterminated string. CodeQL flags the chain as double unescaping.

One regex pass maps each escape exactly once. The regression test
feeds the escaped-backslash program through the validator CLI.
2026-10-19 22:03:57 -04:00
Affaan MustafaandAffaan Mustafa d3c49a80df refactor(ci): split validate-hooks into per-shape validators
validateHookEntry handled command, http and prompt hooks in one function; it now dispatches to validateCommandHook, validateHttpHook and validatePromptHook with the inline node -e check in validateInlineJs. validateHooks reads the file, loads the sidecar and validates the object or legacy array shape through readHooksFile, loadMetadata, validateObjectFormat and validateArrayFormat, so the deepest nesting is gone.

Error messages, their order, exit codes and the --update-fingerprints flow are unchanged.
2026-10-19 22:03:57 -04:00
Affaan MustafaandAffaan Mustafa 35c7681d47 refactor(hooks): break up session-end summary and main flow
extractSessionSummary did user-message filtering and two kinds of tool_use collection in one loop body six blocks deep. The per-entry work now lives in userMessageText, recordToolUse and collectEntry. main() is down to the sequence of steps: resolveTranscriptPath, sessionShortId, maybeGenerateLlmSummary, then updateSessionFile or createSessionFile, with the shared footer and empty-session template as constants.

Call order, log lines, file names and the written markdown are unchanged, including the exact summary block replacement and the migration path for files without markers.
2026-10-19 22:03:57 -04:00
Affaan MustafaandAffaan Mustafa 7b1756670f refactor(hooks): split gateguard gate and classifiers into smaller units
gate() handled Edit, MultiEdit and shell in one 220-line function. It now builds a small context and dispatches to gateSingleEdit, gateMultiEdit and gateShell, with the first-touch, sibling-collapse and routine/destructive shell steps as their own functions. isDestructiveGit and isReadOnlyGitIntrospection became subcommand tables; unwrapLeadWrappers got one handler per wrapper; ddLauncherCommandIndex, isDestructiveFindExec and sanitizePath lost their inline option and code point ladders. condensedGateMsg takes an options object instead of seven positional parameters.

Decision order, recorded metrics reasons, state keys and every denial message are unchanged, and the module exports are the same.
2026-10-19 22:03:57 -04:00
Affaan MustafaandAffaan Mustafa cfcd81c076 refactor(lib): share span readers in shell-substitution
extractSubshellGroups and extractBraceGroups each carried their own copies of the quote-aware skipping for $(...), backtick and (...) spans, which is where the complexity and nesting warnings came from. The skipping now lives in findParenSpanEnd, findBacktickEnd and skipOuterSpan, with readSubshellBody and readBraceBody doing the body collection.

Behavior is unchanged: the same bodies come back in the same order, trailing backslashes and unterminated spans resolve the same way, and the three exports keep their signatures.
2026-10-19 22:03:57 -04:00
Affaan MustafaandAffaan Mustafa 603e1dee1e refactor(hooks): flatten block-no-verify decision tree
checkGitWords, executableWords, shellRole, updateShellState and checkCommand were each well over the complexity budget and checkCommand nested seven blocks deep. Split them into named helpers: git global option scanning and bypass flag search, per-wrapper handlers for command/exec/env/sudo, a shell option cluster classifier, declaration flag parsing, and a per-task/per-state/per-environment pipeline inside checkCommand.

Every budget.spend call keeps its amount and order so the work quota tests still land in the same window. The module still only requires ./lib/shell-scan and exports run unchanged. Wrapper option sets moved to module constants instead of being rebuilt on every call.
2026-10-19 22:03:57 -04:00
Affaan MustafaandGitHub 5af4395e5c test(lib): cover five untested scripts/lib modules (#3641)
* test(lib): cover feedback-links routes and payload

Pins the three public issue routes to the ECC repository and checks each template name actually exists under .github/ISSUE_TEMPLATE. Also locks the ecc.feedback.v1 payload shape, the no-diagnostics-upload promise, and that every call returns fresh copies so a caller cannot alter the frozen route table.

* test(lib): cover cursor-agent-names prefixing and path handling

Pins the ecc- prefix rule the Cursor install applies to agent files: idempotent, lowercase-prefix only, empty names pass through. Covers the relative path variant across backslash, repeated, and trailing separators, and that a leading separator cannot re-root the destination under the target agents directory.

* test(lib): cover agent-tool-map Pi mapping and authority invariant

Pins the Claude to Pi tool table: six core tools, every target a real Pi built-in, and read-only tools never escalating to bash, edit, or write. Covers the unsupported path for MCP, web, unknown, empty, and non-string names, and that prototype member names like constructor are not treated as table hits.

* test(lib): cover compute-sponsor URL and passive copy

Pins the compute URL to the bare https route with no path, query, or credentials, and that the sponsor copy links it exactly once and nowhere else. Locks the wording that keeps the link passive, keeps the ecc ito find bridge opt-in and non-reserving, and does not claim managed inference is live. The existing surface test only reads docs and CLI output, so the module itself had no direct test.

* test(lib): cover invocation-environment precedence and isolation

Pins the three branches every install path relies on: an explicit env is copied and wins, a scoped homeDir yields an empty environment so ambient variables cannot leak into a contained install, and anything else snapshots process.env. Also checks the copy is shallow, own-keys only, and never writes back.
2026-10-19 18:41:26 -04:00
Affaan MustafaandGitHub 8293d0da8f fix(commands): drop unrendered LITE_MODE_FLAG token from codeagent-wrapper calls (#3640)
The multi-backend, multi-frontend, multi-plan, multi-execute and multi-workflow commands were copied from ccg-workflow's command templates, which carry {{LITE_MODE_FLAG}} and {{GEMINI_MODEL_FLAG}} for that project's installer to substitute. ECC has no substitution step, so bash passed the literal token to codeagent-wrapper as a positional argument, the backend name landed in the working-directory slot, and every call exited 1. Remove the tokens from the five commands and the ja-JP, tr and zh-CN docs copies so the wrapper receives a plain --backend invocation. A regression test scans every multi-* command and translated copy for codeagent-wrapper lines that still contain a {{TEMPLATE}} token.

Fixes #3595
2026-10-19 18:41:07 -04:00
Affaan MustafaandGitHub 6c557856af feat(ci): cap open PRs per contributor at ten (#3639)
Extend the PR burst guard with an open-PR cap. On every opened or reopened
PR by a non-collaborator, the guard lists the repository's open PRs, keeps
the author's oldest `maxOpen` (10) open and closes the newer ones with a
bot comment that names the count and the limit. No lock, no maintainer
alert: the cap is about review capacity, not spam. PRs the burst logic
already closed in the same run are excluded so nothing is mutated twice.
Collaborators with write access stay exempt, dry run reports without
mutating, and the comment is deduplicated on a bot-authored marker.

Haley asked for this on 2026-10-19: each contributor should only have 10
to 15 PRs open at a time. Existing open PRs are not bulk-closed; the cap
applies as each author opens or reopens their next PR.

Verification: 22 unit tests and the HTTP workflow test pass,
validate-workflow-security passes, eslint and markdownlint clean. Dry run
against affaan-m/ECC on #3621 reports openCount 19 and nine cap excess
PRs for that author, with no writes.
2026-10-19 18:08:53 -04:00
haelyraandGitHub 76aaa77df6 Merge pull request #3596 from affaan-m/feat/pr-burst-protection
feat(ci): limit PR bursts and alert maintainers
2026-10-15 15:17:00 -04:00
haelyra 0cf3a25d57 docs(ci): keep PR moderation limited to submission rate 2026-10-15 15:16:13 -04:00
haelyra 0ad248d199 feat(ci): guard PR submission bursts and alert maintainers 2026-10-15 14:33:45 -04:00
haelyraandGitHub b92f181b3b Merge pull request #3520 from affaan-m/integration/ecc-043-followup-20261011
fix: deliver ten focused guard, migration and evaluation repairs
2026-10-11 22:02:10 -04:00
haelyra 9fdf1ca277 test: recognize unavailable Windows symlink privilege 2026-10-11 20:45:01 -04:00
haelyra 70f571e205 test: drain synthetic scanner input before reporting status 2026-10-11 20:23:42 -04:00
haelyra d0f5632287 fix: reject linked sandbox bases before scenario cleanup 2026-10-11 19:59:01 -04:00
haelyra 345cd364a3 test: accept Windows directory refusal before piped evaluator input 2026-10-11 19:41:13 -04:00
haelyra 6cb9f0a162 fix: distinguish auth failures from ordinary provider discussion 2026-10-11 19:16:09 -04:00
haelyra 8d969b0ec4 fix: retain authentication diagnostics across empty stream blocks 2026-10-11 19:01:56 -04:00
haelyra 2ec80189a4 fix: preserve missing-result auth diagnostics and bound fixture contention 2026-10-11 18:46:07 -04:00
haelyra 6ef38a2993 fix: validate evaluator files before pipe reads and strengthen grader controls 2026-10-11 17:54:29 -04:00
haelyra cfeb773d96 fix: reject constant grader output and classify overflow errors 2026-10-11 17:32:22 -04:00
haelyra b71b832bf0 fix: reject malformed classifier values before reporting 2026-10-11 16:42:17 -04:00
haelyra ba8595b43f test: annotate classifier controls and bind canonical resources 2026-10-11 16:35:54 -04:00
haelyra f6fe47de27 merge: preserve latest contributor CSV grading repair 2026-10-11 16:22:18 -04:00
haelyra ae4bc283ae fix: preserve classifier parse failures through compliance grading 2026-10-11 16:02:31 -04:00
haelyra 1aed82de24 fix: refresh trigger registry binding after evaluator repair 2026-10-11 15:49:18 -04:00
haelyra 3515db6aad fix: preserve evaluator input and audit contracts across platforms 2026-10-11 15:39:40 -04:00
haelyra 1d1b62e58e fix: recover plugin migration at the effective settings scope 2026-10-11 15:36:49 -04:00
haelyra 6c9c25158a fix: address evaluator portability and recording review findings 2026-10-11 15:35:17 -04:00
drakeo338 7b34638500 fix: raise on unparseable skill-comply classifier output
_parse_classification returned {} for garbage or non-dict output, so a failed classification looked like zero matched steps and graded as non-compliant. Raise ClassifierParseError (a RuntimeError, like the non-zero-rc path) instead.
2026-10-11 19:21:15 +00:00
haelyra 87c136fcae fix: integrate strict issue targeting and Windows Python discovery 2026-10-11 15:07:29 -04:00
haelyra d60c90708c test: exercise real Python discovery failure controls 2026-10-11 15:05:36 -04:00
haelyra 03f9a59bc7 test: separate stdin fixture startup budget from drain deadline 2026-10-11 15:04:53 -04:00
haelyra acc453d357 Merge remote-tracking branch 'origin/pr-3524' into steward/late-arrivals-20261011 2026-10-11 15:00:38 -04:00
haelyra c7a467061b Merge remote-tracking branch 'origin/pr-3523' into steward/late-arrivals-20261011 2026-10-11 15:00:38 -04:00
haelyraandGitHub d4a44ded8c Merge pull request #3511 from affaan-m/integration/ecc-043-incoming-20261011
fix: integrate nine focused skill, instinct and documentation repairs
2026-10-11 14:37:53 -04:00
montjeffrey 72f2105cf6 test: run the Hermes hook tests with a resolved Python 3 on Windows
- windows-test-env.js gains resolvePython: it probes each candidate with
  `-c "import sys; sys.exit(0 if sys.version_info[0] == 3 else 1)"`, so the
  Store stub is rejected.
- hermes-hooks.test.js launches its four hook spawns through the resolved
  interpreter, falling back to python3 when none is found so a machine
  without Python still fails loudly instead of skipping.

hermes-hooks goes from 0/14 to 14/14 on Windows 11; the other users of the
helper are unchanged. Product code is untouched: Hermes runs these hooks
itself and the installer writes no interpreter.
2026-10-11 14:21:25 -04:00
montjeffrey e9efbc2626 test: pin a Python resolver that skips the Windows Store python3 stub
tests/hermes-hooks.test.js spawns python3, which on Windows is usually the
Microsoft Store alias stub: it exits 9009 instead of running Python, so all
14 Hermes cases fail with "hook must always exit 0 (got 9009)". python.org
installs provide python and the py launcher, not python3.

Pin resolvePython({ platform, probe }) in the shared windows-test-env
helper: the first candidate that actually runs Python 3 (Windows: python,
py -3, python3; elsewhere: python3, python), or null when none does, plus a
real smoke run of the resolved interpreter.

Against main: 4 of 8 windows-test-env cases fail (no resolvePython).
2026-10-11 14:21:24 -04:00
haelyra 1b7cf4e417 test: align alias failure bounds with reviewed Windows writer retry policy 2026-10-11 14:18:52 -04:00
montjeffrey 58f7021a64 fix(gateguard): fix the CSV grader's expected values before the export runs
Snapshot the header and expected rows when the grader loads and pass
exportCsv copies, so an exporter that overwrites its input cannot change
what it is compared with. decoy-mutates now scores 0.75 with the other
two decoys; reference still scores 1.
2026-10-11 14:14:13 -04:00
montjeffrey deb5d0a1d0 test(gateguard): pin a CSV decoy that overwrites its input rows
The CSV grader reads its expected values from the same ROWS objects it
passes to exportCsv, so an exporter that overwrites the input fields and
exports them scores 1 (Greptile on #3519). decoy-mutates does exactly
that; graderIsSound reports the grader unsound on this head
(decoy-mutates=1). The grader-soundness test now prints every decoy
score through formatGraderScores.
2026-10-11 14:14:13 -04:00
haelyra 2187cdb49f test: carry bounded native eval CLI startup checks into follow-up batch 2026-10-11 13:50:05 -04:00
haelyra a4d9297da1 fix: allow bounded sustained Windows atomic replacement contention 2026-10-11 13:47:57 -04:00
haelyra ee77b3a930 test: allow bounded CLI startup on loaded runners 2026-10-11 13:45:04 -04:00