Skip to content

feat: confirm-before-execute prefix syntax for destructive Opsfile commands #21

@seanseannery

Description

@seanseannery

Problem This Solves

Operational Opsfiles often contain both safe read-only commands (tail logs, check alarms) and destructive remediation commands (rollback, restart, scale-down). Currently there is no way to distinguish them at the Opsfile level — ops prod rollback executes immediately with no confirmation, the same as ops prod tail-logs.

During high-pressure on-call situations this is a liability. A mistyped command or accidental keypress can trigger a rollback or service restart before the operator intended.

Proposal

Add a ? line prefix to Opsfile shell lines that marks them as requiring interactive confirmation before execution.

Opsfile syntax:

```make
rollback:
default:
? aws ecs update-service
--cluster $(CLUSTER)
--service my-service
--force-new-deployment
--region $(AWS_REGION)

restart-pods:
default:
? kubectl rollout restart deployment/$(DEPLOYMENT)
--namespace $(NAMESPACE)
--context $(CONTEXT)

tail-logs:
default:
aws logs tail $(LOG_GROUP) --follow --region $(AWS_REGION)
```

Runtime behaviour:

When ops reaches a ?-prefixed line during execution it:

  1. Prints the fully resolved command (with variables substituted) to stdout
  2. Prompts the user: Execute? [y/N]:
  3. If the user types y or Y (+ Enter), executes the command normally
  4. If the user types anything else or presses Enter, it stops and all subsequent commands will not be executed
    4.a However if the prefix - is also included on that line, it will skips the line and prints Skipped. and proceed executing subsequent bash commands.

The ? prefix may be combined with - (ignore-error) and @ (suppress-echo) prefixes in any order: ?-, -?, ?@, @?, ?-@, -@?, etc.

Interaction with existing flags:

  • --dry-run: ?-prefixed lines are printed (as with all lines) but no prompt is shown and nothing executes
  • --silent: ?-prefixed lines are prompted normally (silent suppresses output, not safety prompts)

Example session:

```
$ ops prod rollback
? aws ecs update-service --cluster my-service-prod --service my-service --force-new-deployment --region us-east-1
Execute? [y/N]: y
... (aws output) ...

$ ops prod rollback
? aws ecs update-service --cluster my-service-prod ...
Execute? [y/N]:
Skipped.
```

Acceptance Criteria

Parser:

  • ? is recognised as a valid line prefix in environment shell line blocks, stripped before storing the line
  • ? may be combined with - and @ in any order; all three are stripped independently before storing
  • A ?-prefixed line is stored with a Confirm bool flag in the resolved line representation (or equivalent)
  • Lines without ? are unaffected

Executor:

  • When a confirmed line is reached and stdin is a TTY: print the resolved command, prompt Execute? [y/N]: , read one line of input
  • y or Y executes the command; any other input (including empty) skips it and prints Skipped.
  • When stdin is not a TTY (piped/scripted): skip the confirmation prompt and execute the line (non-interactive mode must not hang)
  • --dry-run: ?-prefixed lines are printed with a [confirm] annotation; no prompt shown
  • Exit code behaviour is unchanged: a confirmed line that exits non-zero still stops execution (unless - is also set)

Tests:

  • Parser test: ?-prefixed lines parsed correctly, confirm flag set
  • Parser test: combined prefixes (?-, -?@) all stripped correctly
  • Executor test: y input executes; non-y input skips
  • Executor test: non-TTY stdin executes without prompting
  • Executor test: --dry-run prints annotation, no prompt

Metadata

Metadata

Assignees

No one assigned

    Labels

    P3 - Low PriorityGet to it when you can. Is affecting very few users or has a questionable return in valueenhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions