Skip to content

feat: add Zero hook backend#43

Merged
gnanam1990 merged 2 commits into
mainfrom
feat/m4-hook-backend
Jun 4, 2026
Merged

feat: add Zero hook backend#43
gnanam1990 merged 2 commits into
mainfrom
feat/m4-hook-backend

Conversation

@gnanam1990

@gnanam1990 gnanam1990 commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Add a Zero hook backend for layered user/project hook configuration, enablement, matching, and diagnostics.
  • Add hook audit JSONL persistence for started/completed hook execution events with stable sequence ordering.
  • Expose zero hooks list in text and JSON formats so CLI users can inspect configured hooks and load diagnostics.

Details

  • Supports default hook paths from XDG config/data homes with project-level overrides from .zero/hooks.json.
  • Keeps valid hook entries available while reporting malformed or duplicate configuration as diagnostics.
  • Adds config-store helpers for list/upsert/remove/enable flows and selector helpers for event/tool matching.
  • Adds focused coverage for config layering, persistence, selection, audit storage, and CLI output.

Validation

  • bunx tsc --noEmit
  • bun test ./tests --timeout 15000 (274 pass)
  • bun run build
  • bun run smoke:build
  • ./zero --help
  • ./zero hooks list
  • ./zero hooks list --json
  • git diff --check origin/main..HEAD

Summary by CodeRabbit

  • New Features

    • Added a zero hooks list CLI subcommand with JSON and formatted text output
    • Hook configuration management: add, remove, enable/disable, and layered user/project settings
    • Audit logging for hook execution events with timestamps and sequence numbers
    • Configuration diagnostics to report errors and conflicts
  • Tests

    • End-to-end tests covering config, audit, CLI output, concurrency, and secret redaction

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown
Contributor

Zero automated PR review

Verdict: No blockers found

Blockers

  • None found.

Validation

  • [pass] Diff hygiene: git diff --check
  • [pass] Typecheck: bun run typecheck
  • [pass] Tests: bun run test
  • [pass] Build: bun run build
  • [pass] Smoke build: bun run smoke:build

Scope

Head: 3c612814ef35
Changed files (6): src/index.ts, src/zero-hooks/audit.ts, src/zero-hooks/config.ts, src/zero-hooks/index.ts, src/zero-hooks/types.ts, tests/zero-hooks.test.ts

This deterministic review checks validation status and basic diff hygiene. A human reviewer still owns product judgment and design quality.

@anandh8x anandh8x left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's good

  • Layered config (user + project) with XDG_CONFIG_HOME / XDG_DATA_HOME resolution, overrideable via cwd / env injection — the test harness exploits this cleanly.
  • Zod schema validation with structured diagnostics (io / json / schema / duplicate) — useful for surfacing errors without failing the whole load.
  • Project-overrides-user semantics with a duplicate diagnostic when an id collides, and a stable alphabetical sort of merged hooks.
  • Atomic config writes via temp file + rename in writeZeroHooksConfig (src/zero-hooks/config.ts:130-136).
  • redactZeroSecrets is applied to the JSON output of hooks list --json (src/index.ts:444), consistent with the other redaction boundaries in the CLI.
  • Test coverage spans config layering, persistence round-trip via the store, selector matching, audit JSONL, and end-to-end CLI output as a subprocess.

Observations (non-blocking)

  1. Audit append is not serialized. ZeroHookAuditStore.append (src/zero-hooks/audit.ts:60-72) computes sequence via readEvents().length + 1 and then appendFiles. Two concurrent appendStarted / appendCompleted calls would compute the same sequence and the second writer's line would land out of order relative to sequence numbers — so the "stable sequence ordering" promised in the PR body isn't actually stable under concurrency. The ZeroMcpPermissionStore in #40 used a withWriteLock promise chain for the same pattern; reusing the same shape (or in-process mutex around the read+append pair) would close it.

  2. ZeroHookConfigStore.list user-bypass hack. new ZeroHookConfigStore({ configPath }).list() (src/zero-hooks/config.ts:154-159) passes ${this.configPath}.user-missing to force the user layer to be absent, rather than reading a single file. It works but is opaque; a loadZeroHooksConfigFromPath(path) (or a source: 'project' | 'user' filter on the existing loader) would read more directly.

  3. CLI doesn't surface the audit store yet. ZeroHookAuditStore.readEvents() exists and is tested, but zero hooks list (src/index.ts:431-449) only shows config. A follow-up hooks list --audit (or hooks audit) subcommand would make the audit file discoverable from the CLI without users hunting for ~/.local/share/zero/hooks/audit.jsonl.

  4. Matcher support is *-only. matchesHookMatcher (src/zero-hooks/config.ts:248-255) handles exact match and * wildcards only — no ? / [abc]. Worth a one-line doc comment on ZeroHookDefinition.matcher so users know what to expect.

No blockers. The race in #1 is the only one I'd want to see fixed before this lands in main.

@gnanam1990

Copy link
Copy Markdown
Collaborator Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai

coderabbitai Bot commented Jun 4, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a zero hooks subsystem: types and barrel exports, layered config loading/merge and a CRUD store, selection/formatting utilities, a file-backed JSONL audit store, CLI "hooks list" command with redaction, and integration tests.

Changes

Zero Hooks Configuration and Audit System

Layer / File(s) Summary
Type System and Exports
src/zero-hooks/types.ts, src/zero-hooks/index.ts
Foundational types for hook events, diagnostics, load paths/results, audit event shapes, and a barrel export for the zero-hooks module.
Config Backend: Loading, Merging, CRUD, Formatting
src/zero-hooks/config.ts
Path resolution (env/CWD), layered JSON config loading with diagnostics, merge rules (last-layer-wins + duplicate diagnostics), atomic write via temp+rename, ZeroHookConfigStore (list/upsert/remove/setEnabled) with per-path mutation lock, selection by event and wildcard matcher, and formatZeroHookList.
Audit Backend: JSONL Event Store
src/zero-hooks/audit.ts
File-backed JSONL audit store with appendStarted/appendCompleted producing typed events with auto-incremented sequence and ISO timestamps, serialized appends via internal queue, and readEvents that skips malformed lines while warning.
CLI Integration: hooks list
src/index.ts
New hooks list command that loads hook config + diagnostics, outputs redacted JSON with --json or formatted text otherwise (formatted output redacted), and sets non-zero exit code on errors.
Integration Tests
tests/zero-hooks.test.ts
End-to-end tests validating path resolution, layered loading and diagnostics, store persistence and concurrent mutation serialization, selection/matching behavior, audit sequencing and malformed-line tolerance, and CLI outputs with secret redaction.

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant loadZeroHooksConfig
  participant formatZeroHookList
  participant redactZeroString
  CLI->>loadZeroHooksConfig: load config + diagnostics
  loadZeroHooksConfig->>CLI: ZeroHookLoadResult
  alt --json
    CLI->>CLI: redactZeroSecrets(JSON)
  else text
    CLI->>formatZeroHookList: format config + diagnostics
    formatZeroHookList->>redactZeroString: formatted text
    redactZeroString->>CLI: redacted text
  end
  CLI->>CLI: write stdout/stderr or set exitCode
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Suggested reviewers

  • anandh8x
  • Vasanthdev2004
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title "feat: add Zero hook backend" clearly and directly summarizes the main change—introducing a new Zero hook configuration, audit, and CLI backend system.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/m4-hook-backend

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (2)
tests/zero-hooks.test.ts (2)

31-55: ⚡ Quick win

Anchor the spawned CLI path to the test file.

Line 35 resolves src/index.ts from process.cwd(), so this test can fail when Bun is launched from a subdirectory or an IDE runner. Resolve the entrypoint from import.meta.dir instead to keep it deterministic.

Suggested change
 async function runZeroHooks(
   cwd: string,
   args: string[] = []
 ): Promise<{ exitCode: number; stdout: string; stderr: string }> {
-  const child = Bun.spawn([process.execPath, join(process.cwd(), 'src/index.ts'), 'hooks', ...args], {
+  const cliEntrypoint = join(import.meta.dir, '..', 'src', 'index.ts');
+  const child = Bun.spawn([process.execPath, cliEntrypoint, 'hooks', ...args], {
     cwd,
     env: {
       ...process.env,
       HOME: join(cwd, 'home'),

As per coding guidelines, tests/**/*.ts: Review tests for Bun test idioms, deterministic behavior, and meaningful coverage of safety decisions, provider/runtime flows, session events, and TUI command behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/zero-hooks.test.ts` around lines 31 - 55, The test's CLI spawn in
runZeroHooks resolves 'src/index.ts' relative to process.cwd(), causing
nondeterministic failures; update the spawn arguments to resolve the entrypoint
using import.meta.dir (e.g., join(import.meta.dir, 'src/index.ts')) so the child
process always launches the correct CLI from the test file's directory; keep the
rest of runZeroHooks (env, pipes, and return structure) unchanged.

216-255: ⚡ Quick win

Add coverage for malformed audit lines.

This only proves the happy path. The audit reader's invalid-JSONL recovery is part of the backend contract in this PR, so a regression there would still pass this suite. Seed the file with one malformed line between two valid events and assert readEvents() preserves the valid entries and ordering.

As per coding guidelines, tests/**/*.ts: Review tests for Bun test idioms, deterministic behavior, and meaningful coverage of safety decisions, provider/runtime flows, session events, and TUI command behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/zero-hooks.test.ts` around lines 216 - 255, The current
ZeroHookAuditStore test only covers the happy-path JSONL read/write flow, so add
a malformed audit line case to exercise invalid-JSONL recovery. In the existing
`appends and reads hook audit events as JSONL` test, seed the audit file with
one bad line between two valid events, then verify `readEvents()` still returns
only the valid entries in the correct order. Keep the assertions aligned with
`ZeroHookAuditStore.readEvents()` behavior and the existing sequence/type
checks.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/zero-hooks/audit.ts`:
- Around line 55-59: readEvents() currently throws on a malformed JSON line
which blocks append() because append() calls readEvents() to compute the next
sequence; change readEvents() to tolerate and recover from malformed lines when
used for append by skipping lines that fail JSON.parse (log a warning including
the line index and raw content) and continue building the events array so
sequence numbers can be computed; implement this either by adding an optional
parameter to readEvents(e.g., tolerateMalformed = false) and, when true (used by
append()), skip/record malformed lines instead of throwing, or by catching parse
errors inside the loop and continuing, ensuring append() still gets a correct
last sequence.
- Around line 64-76: The append method assigns sequence numbers by reading
current events then writing, which is racy under concurrent append calls;
serialize append operations in-process (e.g., add a private in-memory
mutex/queue on the class such as an appendLock or appendQueue) so that append()
obtains the lock, calls readEvents(), computes sequence, writes the file (mkdir
+ appendFile), and then releases the lock; ensure the lock is always released on
success or error so callers don't deadlock and keep using existing symbols
append, readEvents, auditPath, and now to locate and update the logic.

In `@src/zero-hooks/config.ts`:
- Around line 22-31: HookDefinitionSchema currently allows a "matcher" for all
events but selectZeroHooks ignores matched hooks when toolName is absent, which
silently makes sessionStart/sessionEnd hooks with a matcher impossible to
trigger; update HookDefinitionSchema to reject matcher for session hooks (or
emit a validation diagnostic) by adding a Zod refinement/superRefine on
HookDefinitionSchema that checks event (from HookEventSchema) and fails if event
is "sessionStart" or "sessionEnd" while matcher is present; also apply the same
validation change where similar schema logic exists (the other occurrence around
the 170-174 area) so any hook definitions for sessionStart/sessionEnd are
explicitly invalid when matcher is provided and produce a clear error message
referencing the field "matcher".
- Around line 124-160: The upsert/remove/setEnabled methods perform
read-modify-write against the same file (via list and writeZeroHooksConfig)
without any serialization, so concurrent commands can overwrite each other;
modify these methods (upsert, remove, setEnabled) to serialize mutations by
adding a file/operation lock or an optimistic-revision check around list ->
compute nextHooks -> writeZeroHooksConfig using this.configPath, e.g. obtain a
mutex or lock per configPath before calling list and release after
writeZeroHooksConfig, or include a revision/timestamp in the stored config and
retry the read-modify-write if the revision changed; ensure
normalizeHookDefinition, writeZeroHooksConfig and list are used within the
locked/transactional section and that methods return the same values on
success/failure as before.
- Around line 297-305: The matcher construction in matchesHookMatcher currently
builds an unbounded RegExp from hooks.json wildcards (via splitting and joining
to '.*'), which can be abused by many '*' segments; replace this by a safe
linear glob matcher: in matchesHookMatcher, split matcher on '*' and perform
sequential substring/anchor checks against toolName (handle leading/trailing '*'
as prefix/suffix rules) instead of new RegExp, or alternatively add strict
validation in the schema that enforces a maximum total length and a max count of
'*' before constructing any RegExp; update/selectZeroHooks tests to include
multi-'*' patterns and edge cases to cover the new behavior. Ensure you
reference the matchesHookMatcher function and the matcher validation where
hooks.json is parsed/validated.

---

Nitpick comments:
In `@tests/zero-hooks.test.ts`:
- Around line 31-55: The test's CLI spawn in runZeroHooks resolves
'src/index.ts' relative to process.cwd(), causing nondeterministic failures;
update the spawn arguments to resolve the entrypoint using import.meta.dir
(e.g., join(import.meta.dir, 'src/index.ts')) so the child process always
launches the correct CLI from the test file's directory; keep the rest of
runZeroHooks (env, pipes, and return structure) unchanged.
- Around line 216-255: The current ZeroHookAuditStore test only covers the
happy-path JSONL read/write flow, so add a malformed audit line case to exercise
invalid-JSONL recovery. In the existing `appends and reads hook audit events as
JSONL` test, seed the audit file with one bad line between two valid events,
then verify `readEvents()` still returns only the valid entries in the correct
order. Keep the assertions aligned with `ZeroHookAuditStore.readEvents()`
behavior and the existing sequence/type checks.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 451befde-e48f-4627-92d0-c21cf955d8cd

📥 Commits

Reviewing files that changed from the base of the PR and between 10f749e and 622fae7.

📒 Files selected for processing (6)
  • src/index.ts
  • src/zero-hooks/audit.ts
  • src/zero-hooks/config.ts
  • src/zero-hooks/index.ts
  • src/zero-hooks/types.ts
  • tests/zero-hooks.test.ts

Comment thread src/zero-hooks/audit.ts
Comment thread src/zero-hooks/audit.ts Outdated
Comment thread src/zero-hooks/config.ts
Comment thread src/zero-hooks/config.ts Outdated
Comment thread src/zero-hooks/config.ts Outdated
@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

Blockers

  • zero hooks list text output leaks secret-looking hook arguments from .zero/hooks.json. The JSON path is wrapped in redactZeroSecrets, but the text path calls formatZeroHookList(result.config, result.diagnostics) directly and prints [hook.command, ...hook.args].join(' '). I verified this with a temp project hook whose args contained an assembled OpenAI-shaped key: hooks list --json removed the raw value and included [REDACTED], but plain hooks list printed the raw value. Hook config is a diagnostic surface and hook commands/args are likely to contain API keys, bearer tokens, webhook URLs, or other secret-bearing values, so the text formatter needs to redact before printing and should have a regression test for both JSON and text outputs.

Non-Blocking

  • The hook execution/audit backend is still config/list/audit storage only; I did not find execution wiring into the agent loop in this PR. That is fine for this scope, but future execution wiring should keep hooks fail-closed behind explicit permission/safety boundaries.
  • ZeroHookAuditStore.append() computes sequence by reading the whole audit file and then appending, so concurrent in-process appends can race and duplicate/out-of-order sequence values. This is probably acceptable for a first backend layer if execution is not wired yet, but it should be serialized before hooks can run from multiple concurrent calls.
  • matcher is accepted on sessionStart/sessionEnd hooks even though selectZeroHooks() requires toolName when a matcher exists, so those session hooks become unselectable. Either reject matcher for session events with a schema diagnostic or define a clear matching contract for session events.

Looks Good

  • Layered user/project config loading keeps valid layers alive when another layer is malformed and emits structured diagnostics.
  • Project hooks override user hooks deterministically with a duplicate diagnostic and stable id sorting.
  • Hook ids/events/commands are schema-validated before they enter the normalized config.
  • hooks list --json already routes through redactZeroSecrets and did redact the same probe secret correctly.

Validation

  • bun run typecheck — pass.
  • bun test tests/zero-hooks.test.ts --timeout 15000 — 7 pass / 0 fail.
  • bun test ./tests --timeout 15000 — 274 pass / 0 fail.
  • bun run build — pass.
  • bun run smoke:build — pass.
  • git diff --check — pass.
  • CLI probes: zero hooks --help, zero hooks list --help, and temp-project redaction probe for both text and JSON hook-list outputs. The redaction probe is the blocker above.

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Requesting changes because plain-text zero hooks list leaks raw secret-bearing hook args while the JSON path redacts them. Full details and validation are in my review comment.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/zero-hooks/audit.ts (1)

66-86: Append serialization looks correct; full-file read per append is a deferred scalability concern.

The in-process appendQueue resolves the sequence race, and max(sequence)+1 is robust against gaps. Note that each append re-reads and parses the entire audit file to compute the next sequence — that's O(n) per write / O(n²) over the log's lifetime. Fine while execution isn't wired, but cache the last sequence in memory (refreshed from disk on init) before this is exercised on a hot path. The per-instance queue also won't serialize two ZeroHookAuditStore instances (or processes) targeting the same auditPath, so don't rely on it for cross-process ordering.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/zero-hooks/audit.ts` around lines 66 - 86, Append currently re-reads the
entire audit file in append() via readEvents() to compute sequence, causing O(n)
per write; add an in-memory lastSequence property on ZeroHookAuditStore
initialized by reading/parsing the file once (e.g., in the constructor or an
async init method that calls readEvents() once) and use lastSequence+1 in
append() instead of recomputing from readEvents(); ensure append() updates
lastSequence after writing the event and keep existing appendQueue usage for
intra-process serialization (note: this does not solve cross-process ordering
for multiple instances writing to the same auditPath).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/zero-hooks/audit.ts`:
- Around line 66-86: Append currently re-reads the entire audit file in append()
via readEvents() to compute sequence, causing O(n) per write; add an in-memory
lastSequence property on ZeroHookAuditStore initialized by reading/parsing the
file once (e.g., in the constructor or an async init method that calls
readEvents() once) and use lastSequence+1 in append() instead of recomputing
from readEvents(); ensure append() updates lastSequence after writing the event
and keep existing appendQueue usage for intra-process serialization (note: this
does not solve cross-process ordering for multiple instances writing to the same
auditPath).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: db57a67f-dc02-4e48-b3f8-3ac6a449fd48

📥 Commits

Reviewing files that changed from the base of the PR and between 622fae7 and 3c61281.

📒 Files selected for processing (4)
  • src/index.ts
  • src/zero-hooks/audit.ts
  • src/zero-hooks/config.ts
  • tests/zero-hooks.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/index.ts

@Vasanthdev2004

Copy link
Copy Markdown
Collaborator

Blockers
None.

Non-Blocking

  • This PR is still hook config/list/audit storage only; I do not see runtime hook execution wiring in the agent loop yet. Future execution wiring should keep hooks permissioned/fail-closed before any command runs.
  • ZeroHookConfigStore and ZeroHookAuditStore now serialize in-process mutations/appends. That covers the current single-process CLI/backend use case, but multi-process writers could still race because there is no filesystem lock. I would keep that as a follow-up before exposing hooks as a frequently-running runtime surface.

Looks Good

  • The previous blocker is fixed at head 3c61281: both plain text zero hooks list and zero hooks list --json now redact hook args containing an assembled OpenAI-shaped key. I verified the exact raw value is absent from both outputs and [REDACTED] appears in both.
  • Session hook matcher ambiguity is fixed: sessionStart/sessionEnd hooks with matcher now fail schema validation with fieldPath: hooks.0.matcher, and the invalid hook is not loaded.
  • Audit reads now tolerate malformed JSONL lines without blocking later appends, and append sequencing is serialized in-process.
  • Config store mutations are serialized in-process for the same config path, avoiding the earlier same-process read/modify/write clobber.
  • Wildcard matcher logic was changed to a linear matcher rather than building a RegExp from hook config.

Validation

  • bun run typecheck — pass.
  • bun test tests/zero-hooks.test.ts --timeout 15000 — 10 pass / 0 fail.
  • bun test ./tests --timeout 15000 — 277 pass / 0 fail.
  • bun run build — pass.
  • bun run smoke:build — pass.
  • git diff --check — pass.
  • CLI redaction probe from a temp project with isolated HOME/USERPROFILE/XDG dirs — pass for text and JSON outputs.
  • Session matcher schema probe from a temp project — pass.
  • GitHub checks at review time: Ubuntu smoke, macOS smoke, Windows smoke, Performance Smoke, Zero Review, and CodeRabbit all success.

@Vasanthdev2004 Vasanthdev2004 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved current head 3c61281 after verifying the hook-list redaction blocker and session-matcher/schema hardening are fixed, with local validation passing.

@gnanam1990
gnanam1990 merged commit a6ab274 into main Jun 4, 2026
6 checks passed
@Vasanthdev2004
Vasanthdev2004 deleted the feat/m4-hook-backend branch June 28, 2026 08:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants