Skip to content

feat(miner-foundation): PreToolUse-style deny-hook primitives for gittensory-miner #2295

Description

@JSONbored

Pull forward (from the roadmap's later Phase 5) the hook-enforced house-rule primitives: a small, pure evaluateDenyHooks(toolCall: { name: string; input: Record<string, unknown> }, rules: DenyRule[]): { allowed: boolean; reason?: string } mechanism modeled on Claude Code's PreToolUse deny-hook shape, so that even in this foundation phase, the miner package has a checked, testable place to enforce house rules ("never touch .github/workflows/**", "never run git push --force", "never read/write .env") BEFORE any later phase wires an actual coding-agent tool-call loop through it. This issue implements the deterministic rule-evaluator only — there is no live tool-call interception yet (that needs a real coding-agent driver, out of scope for Phase 0), but the primitive and its rule format exist and are fully tested so later phases just plug a real event source into it.

Deliverables

  • A deny-hooks module exporting a DenyRule type (e.g. { matcher: string /* tool-name glob or exact */; pathPattern?: string /* glob against a path-shaped input field */; reason: string }) and a pure evaluateDenyHooks(toolCall, rules): { allowed: boolean; blockedBy?: DenyRule }.
  • A small built-in default rule set covering the repo's own house rules as a starting example: block any tool call whose input touches .github/workflows/**, .env*, or any path matching **/secret*/** or **/*private*key* (mirroring the forbidden-path patterns already enforced in scripts/check-mcp-package.mjs), and block any shell-command-shaped tool call containing --force combined with push (a conservative git-force-push guard).
  • Unit tests: each built-in rule fires on a crafted matching tool call and does NOT fire on a clearly benign one (both sides of every rule, per the repo's own branch-coverage discipline); an empty rule set always allows; a tool call matching zero rules is allowed.
  • Doc comment stating explicitly that this module NEVER executes or intercepts anything live in this phase — it is a pure decision function a later phase's real hook wiring will call.
  • gittensory-miner doctor (from the CLI-entry-point issue) gains a line confirming the deny-hook module loads and its default rule set is non-empty, so "the safety primitive exists and is wired at least this far" is checkable from day one.

References

  • scripts/check-mcp-package.mjs (forbiddenPath/forbiddenContent regexes, lines 15-16) — existing house-rule-as-regex precedent in this exact repo to mirror for the built-in default rules.
  • src/settings/autonomy.ts (resolveAutonomy, isActingAutonomyLevel) — THE reusable autonomy dial the phase brief points to; this deny-hook module is a complementary, lower-level primitive (blocks specific dangerous actions outright) rather than a replacement for the autonomy level system (which gates whether acting is allowed AT ALL) — cite both so a reviewer understands they compose rather than duplicate.
  • Phase brief: "pull forward hook-enforced house-rule primitives early (PreToolUse-style deny hooks) since the roadmap explicitly says to pull these forward from Phase 5."
  • New path: packages/gittensory-miner/lib/deny-hooks.js.

Metadata

Metadata

Assignees

No one assigned

    Labels

    gittensor:featureGittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.help wantedExtra attention is needed

    Projects

    Status
    Done

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions