30 Days of AIDay 28 of 30 · Week 4: Enterprise Workflows
Course outline▾

Week 4 · Enterprise Workflows

  1. Day 22Autonomous Agents — From Passive LLMs to Goal-Driven Execution
  2. Day 23Tool Use and Function Calling — Connecting LLMs to APIs, Databases and Shells
  3. Day 24Multi-Agent Orchestration — Supervisor, Worker and Evaluator Patterns
  4. Day 25Automated CI/CD — Automating the Software Lifecycle for AI Models
  5. Day 26Zero-Trust Security for AI — Sandboxing Ephemeral Execution and Model Egress
  6. Day 27Observability and Tracing for Agentic Systems — Telemetry, Logs and Metrics
  7. Day 28Human-in-the-Loop Architecture — Machine Second, Human First in Practice
  8. Day 29Managing Technical Debt, Drift, and Model Governance in Enterprise ITComing soon · 2026-10-29 · 7 PM IST
  9. Day 30The 10-Year Horizon: Architecting IT Strategy for the AI-Native EnterpriseComing soon · 2026-10-30 · 7 PM IST
Open the course page →

Day 28: Human-in-the-Loop Architecture — Machine Second, Human First in Practice

2026-10-28 · 8 min read

Efficiency is the goal of automation, but in high-consequence settings, full autonomy is the wrong target. Actions that change production data, move money, reconfigure network hardware or contact customers should combine the machine's speed with verified human judgment. The principle is Human First, Machine Second.

In plain terms: A junior colleague can read, research and draft all day without asking. But before they wire money or delete a database, they get a sign-off from someone senior.

1. Define the decision boundary

Divide actions into two classes with automatic gates.

  • Reversible, low-impact (fully autonomous): reading documentation, summarising logs, querying read-only metrics, drafting a remediation plan.
  • Irreversible or high-impact (gated): dropping a table, changing a switch VLAN, deploying to production, approving spending.

Decide the class in code and policy, using an allow-list of action types. Do not ask the model whether its own action is risky, because a confused or manipulated model will answer wrongly.

Sort actions by impact Reversible, low impactFully autonomousRead documentationSummarise logsQuery read-only metricsDraft a planIrreversible, high impactNeeds a human firstDrop a database tableChange a VLAN configDeploy to productionApprove spendingHuman first, machine second where it counts.Set the class in code and policy, not by the model's opinion.
Low-impact reversible actions such as reading docs, summarising logs and drafting plans can run autonomously. Irreversible or high-impact actions such as dropping tables, changing network configuration, deploying to production or approving spend need human approval. The classification is set in code and policy, not by the model.

2. Engineer the approval gate

A human-in-the-loop workflow needs an asynchronous pause and resume inside your orchestration.

  1. Interrupt. When an action is high-impact, the agent stops, saves its state to durable storage and enters a WAITING_FOR_APPROVAL state.
  2. Notify with context. An alert goes to Slack, Teams or a portal with the proposed command, the agent's reasoning and the expected outcome.
  3. Authorise. The human approves or rejects, and the decision is authenticated and signed so it cannot be forged.
  4. Resume or revise. On a verified approval the saved state is restored and the action runs. On a rejection the human's note is added to the agent's context so it drafts a safer alternative.
Pause, ask, resume 1. Interruptagent halts, saves stateWAITING_FOR_APPROVAL2. Notifyalert with command and reasoningSlack, Teams or a portal3. Authorisehuman approves or rejectsauthenticated and signed4. Resume or reviserun it, or plan againstate restored from storage State is saved to a database, so the wait can last hours.
When an action meets the high-impact criteria the agent halts and saves its state, a notification with the proposed command and reasoning goes to a human, the human approves or rejects with authenticated authorisation, and the workflow resumes from stored state or revises its plan.
What the approver sees Approval requested · agent: network-opsProposed commandset vlan 210 on switch-14 ports 3-9WhyTelemetry shows ports 3-9 carrying untagged traffic.Expected outcomeTraffic isolated. Brief reconnect on 7 devices.ApproveReject with noteCommand, reasoning and outcome in one place. Example is illustrative.
A good approval request shows the proposed command, the agent's reasoning and the expected outcome in one place, with approve and reject actions. The example is illustrative.
A rejection teaches the next try Agentproposes a changeHumanrejects with a noteNew plansafer alternative feedback is added to the context window, then the loop repeatsHumans decide. Machines do the legwork.Safe and still fast: people review only what matters.
If the human rejects a proposed action, their note is added to the agent's context so it drafts a safer alternative. This keeps people reviewing only the actions that matter while the machine does the legwork.

Here is the core logic in Python. It assumes a database helper db for saving state and a shared secret for signing approvals. In production you would use your identity provider and a proper signing scheme, and a framework such as LangGraph offers built-in interrupt and resume.

import hmac, hashlib, json

HIGH_IMPACT = {"drop_table", "change_vlan", "deploy_prod", "approve_spend"}   # policy, not model opinion
SECRET = b"load-from-a-secrets-manager"

def execute_or_pause(run_id: str, action: dict, state: dict):
    if action["type"] not in HIGH_IMPACT:
        return perform(action)                                   # reversible: just do it

    db.save(run_id, {"status": "WAITING_FOR_APPROVAL", "action": action, "state": state})
    notify_approvers(run_id, action, reasoning=state["reasoning"])   # command + why + expected outcome
    return "paused"

def sign(run_id: str, decision: str, approver: str) -> str:
    msg = f"{run_id}:{decision}:{approver}".encode()
    return hmac.new(SECRET, msg, hashlib.sha256).hexdigest()

def resume(run_id: str, decision: str, approver: str, signature: str, note: str = ""):
    if not hmac.compare_digest(signature, sign(run_id, decision, approver)):
        raise PermissionError("Invalid approval signature")      # never trust an unsigned decision
    saved = db.load(run_id)
    if decision == "approve":
        return perform(saved["action"])
    saved["state"]["human_feedback"] = note                      # rejection: teach the next attempt
    return replan(saved["state"])

Balancing autonomous reasoning with human oversight keeps the organisation safe while still capturing most of the productivity gain, because people only review the small share of actions that carry real risk.

Coming Up Next

Day 29: Managing technical debt, drift and model governance in enterprise IT.

#HumanInTheLoop #HITL #EnterpriseGovernance #TechLeadership #ProcessAutomation