The shell was never supposed to be an honor system.

Agents and shells can do production damage in one paste. Most teams still rely on convention, shared credentials, and after-the-fact blame.

Valid command. Invalid control model.

Simulate first Approve when needed Audit with identity
operator-shell.zsh
$ kubectl delete job cleanup --all-namespaces --context prod-eu
context sync: prod-us, prod-eu, prod-apac
deleting resources across 3 clusters
post-incident note: "we assumed the context was local"
agent-dispatch.log
$ gh workflow run release.yml --ref main
auth: shared token
requester: whichever identity the dashboard token represents
approval: inferred from vibes
Watch the failure happen

One kubectl line. Real blast radius.

This is the problem Niyam exists to interrupt.

incident reel · cleanup-shell.zsh operator thinks: one cluster
cleanup-shell.zsh context: prod-eu
ticket: remove legacy pods after deploy
$ kubectl delete pods -l app=legacy --all-namespaces --context prod-eu
policy preview: unavailable
scope fan-out detected across prod-us, prod-eu, prod-apac
prod-us
prod-eu
prod-apac
what the operator meant clean one cluster what the shell executed: a region-wide delete path

The problem is structural.

Fast shells. Shared identity. No hard stop before impact.

Shells optimize for speed

They do not pause for risk.

Shared tokens erase ownership

Everyone can act. No one is clearly accountable.

Chat approval is not control

If the shell can still run, the system did not actually stop anything.

Niyam inserts the missing stop.

Before the shell can do damage, Niyam turns the command into a governed decision.

01

Policy simulation

See the risk before execution.

02

Risk and mode assigned

LOW, MEDIUM, or HIGH. DIRECT or WRAPPER.

03

Approval if required

High-risk commands stop until someone explicitly allows them.

04

Execution and audit

Execution stays attributable, reviewable, and durable.

command gh workflow run release.yml
riskLevel HIGH
executionMode WRAPPER
approvalThreshold 2 distinct approvers
identity specific CLI / token

The shell should not be guessing. Niyam answers first.

Bad commands stop feeling routine.

The command pauses before impact.

Risky commands stop instead of rushing through.

High-risk traffic can be forced into wrapper execution.

Dangerous paths stop being “just another shell command.”

Every CLI can have its own actor.

No more “someone used the shared token.”

Not every toolchain should share one skeleton key.

Split identities by person, by CLI, or by agent.

One named token per CLI.

June is June. January is January.

  • Clean separation
  • Clean revocation

Real users plus CLI-specific tokens.

History can say alice via Cursor CLI.

  • Clear responsibility
  • Token-level revocation

This is the zsh hook that intercepts every command.

~/.zshrc · interception hook
# abridged from the current ~/.zshrc
[[ -o interactive ]] || return 0
export NIYAM_CLI_BIN='/Users/prajjwal.kumar/Projects/Niyam/bin/niyam-cli.js'
export NIYAM_INTERCEPT_SESSION_ID="${NIYAM_INTERCEPT_SESSION_ID:-${HOST:-shell}-$$}"

__niyam_zsh_run_local() {
  local raw="$1"
  local dispatch_id="$2"
  eval "$raw"
  local rc=$?
  if [[ -n "$dispatch_id" ]]; then
    NIYAM_INTERCEPT_ACTIVE=1 command "$NIYAM_CLI_BIN" report-local-result ...
  fi
  return $rc
}

__niyam_accept_line() {
  emulate -L zsh
  local raw="$BUFFER"
  local trimmed="${raw#"${raw%%[![:space:]]*}"}"
  local first_token="${${(z)raw}[1]}"

  if [[ "${trimmed[1]}" == "#" || "$first_token" == "niyam-cli" || "$first_token" == "niyam-on" || "$first_token" == "niyam-off" || "$first_token" == "$NIYAM_CLI_BIN" ]]; then
    eval "$raw"        # don't intercept Niyam's own commands
    return $?
  fi

  local local_file="${TMPDIR:-/tmp}/niyam-dispatch.$$.$RANDOM"
  NIYAM_INTERCEPT_ACTIVE=1 command "$NIYAM_CLI_BIN" dispatch \
    --command "$raw" \
    --shell zsh \
    --session-id "$NIYAM_INTERCEPT_SESSION_ID" \
    --working-dir "$PWD" \
    --local-output-file "$local_file"
  local rc=$?
  local local_result="$(<"$local_file")"

  case "$rc" in
    85)
      local dispatch_id="${local_result#dispatch_id=}"
      __niyam_zsh_run_local "$raw" "$dispatch_id"
      rc=$?
      __niyam_zsh_safe_finish
      return $rc
      ;;
    86)
      eval "${local_result#local_command=}"   # one-shot bypass path
      return $?
      ;;
    *)
      return "$rc"
      ;;
  esac
}

zle -N accept-line __niyam_accept_line

You can keep trusting vibes.

Or you can put one real control layer between a command and production.

Niyam is the layer between intention and impact.

Run Niyam before the next routine command becomes the incident.
npm install
NIYAM_ADMIN_PASSWORD=change-me NIYAM_EXEC_DATA_KEY=local-dev-key npm start