neqsim-task-workflow · git:20260919.77c34a0 · 2026-09-19 · sha256 f8556b69e37f5f7e

neqsim-task-workflow git:20260919.77c34a0A

Immutable. This exact content is served forever at /api/v1/blob/f8556b69e37f5f7e.

---
name: neqsim-task-workflow
description: "The full NeqSim engineering task workflow that @solve-task orchestrates. USE WHEN: executing any Standard or Comprehensive task end to end - Phase 0 setup and scale classification, Phase 1 scope and research, Phase 1.5 deep analysis, Phase 2 notebooks with benchmark validation and uncertainty/risk, the Phase 1.5->2 and 2->3 quality gates, independent checks, Phase 3 report and work record, Phase 4 knowledge capture, task-type guidance (A-G), delegation to specialist agents, NeqSim Improvement Proposals, engineering interpretation in reports, critical rules, delivery, and lessons learned from solved tasks. Quick tasks need only section 0 of the agent."
last_verified: "2026-09-18"
---

# NeqSim Task Workflow

This is the detailed procedure behind `@solve-task`. The agent file holds the
mandatory first action, the purpose, and the operating principles (section 0);
sections 1-10 below are loaded on demand for Standard and Comprehensive work.
Section numbers are kept so cross-references from the agent and from
`docs/development/TASK_SOLVING_GUIDE.md` stay valid.

---

## 0.5 ── ALWAYS-ON OBLIGATIONS (moved from the agent)

### Keep `user_input.md` up to date through the whole conversation

`user_input.md` is the **reproducibility log** — anyone re-running this task
should be able to recover the exact starting input from it.

**Whenever the user provides new information during the task, append it to
`user_input.md` immediately and verbatim:**

- Answers to your clarifying questions → append to **section 2 (Q&A)**
- Mid-task corrections, scope changes, or new constraints → append to **section 3 (Follow-up)**
- Any value you assume because the user did not specify it → record it in **section 4 (Inferred Assumptions)** with justification

Do NOT paraphrase, summarise, or "clean up" the user's wording. Paste it as
given. Never delete previous entries — only append.

### All downloaded documents go INSIDE the task folder

**All documents retrieved during a task — STID drawings, PI historian exports,
vendor datasheets, P&IDs, literature PDFs, downloaded standards — MUST be saved
to `step1_scope_and_research/references/` within the task folder.**

NEVER download or save task-related files to workspace-level directories like
`output/`, `figures/`, or any path outside `task_solve/YYYY-MM-DD_slug/`.

**For STID/document retrieval scripts:** Always pass the task's `references/`
path as the output directory:
```python
# CORRECT — saves inside the task folder:
out_dir = os.path.join(TASK_DIR, "step1_scope_and_research", "references")

# WRONG — saves outside the task folder:
out_dir = os.path.join(os.path.dirname(__file__), "..", "figures", "stid_docs")  # NEVER DO THIS
```

**For PDF-to-PNG conversion:** Output converted images to the task's `figures/`:
```bash
<python-executable> devtools/pdf_to_figures.py task_solve/YYYY-MM-DD_slug/step1_scope_and_research/references/ \
    --outdir task_solve/YYYY-MM-DD_slug/figures/
```

This ensures every task is self-contained and portable — zip the task folder
and everything needed is inside it.

### Extract every downloaded or supplied document before solving

The `references/` folder is not passive storage. Before any document-derived
value, topology, limit, requirement, or recommendation enters Step 2, route
**every file** through `technical-document-intelligence-agent` using
`neqsim-document-intelligence-extraction`, then through the applicable
document-type/domain reader.

For each file:

1. Preserve the original and record its hash, actual format, revision/date, and
  extraction-tool versions.
2. Run native text and structured-table extraction first. For spreadsheets,
  retain sheets, formulas, merged ranges, hidden rows/columns, headers, and units.
3. Render and assess every page that contains visual or spatial information.
  Use OCR for scans and multimodal vision for drawings, P&IDs, charts, maps,
  photographs, annotations, symbols, topology, and table layout. OCR alone is
  not sufficient for visual engineering content.
4. Extract comprehensively: body text, tables, title blocks, notes, legends,
  appendices, footnotes, figures, plots, revision clouds, and unexpected
  engineering constraints. Do not stop after finding the fields anticipated by
  the initial task description.
5. Package facts with original text/value/unit, page/cell/bounding-box locator,
  method, confidence, normalized value/unit, and review status. Reconcile
  native/OCR/vision outputs without silently resolving conflicts.
6. Record unsupported content, missing expected fields, conflicts, ambiguous
  facts, and safety-critical or confidence-below-0.85 facts as explicit gaps or
  `needs_review` items.

Write `step1_scope_and_research/document_evidence_manifest.json` with one entry
for every file under `references/`, its extraction operations and status, links
to its evidence package(s), and counts of facts/conflicts/gaps/review items.
Summarize the evidence in `notes.md` and preserve fact identifiers in downstream
inputs/results. The number of manifest source entries MUST equal the recursive
file inventory count, excluding generated evidence packages and the manifest
itself. Do not begin Step 2 while any source is `not_started` or silently
unprocessed; record a blocked/manual-review status when extraction cannot run.

---

## 0.6 ── OPERATING ENVIRONMENTS (what each step needs)

The workflow below was written in the NeqSim source checkout. It also runs from
the pip-installed toolkit (`neqsim-dev-setup`, installed automatically by the
core agent plugin's SessionStart hook) and, degraded, from chat with only the
MCP server. Detect the environment first (agent Step 0) and apply this table.

| Step / tool | Workspace (checkout) | Toolkit (pip, no checkout) | Chat-only (MCP) |
|---|---|---|---|
| `neqsim new-task`, `user_input.md`, `study_config.yaml` | yes | yes | create folder by hand from the template layout |
| `neqsim_dev_setup.neqsim_init()` | `target/classes` (latest Java) | packaged JAR from `pip install neqsim` (`ns.JAR_MODE`, `ns.MISSING_CLASSES`) | not available - use MCP `runFlash`/`runProcess`/`runPVT` |
| `recompile=True`, `mvnw`, Java classes + JUnit (NIP implementation) | yes | **no** - write the NIP, do not attempt | no |
| NeqSim Runner (`AgentBridge`, `neqsim_runner`) | yes | yes | no - run scripts directly or use MCP |
| `validate_task_results`, `consistency_checker`, `TaskResultValidator` | yes | yes (Python validators; the Java `TaskResultValidator` needs the JAR, available) | Python validators not installed - state results.json was not gate-checked |
| `neqsim report` / `generate_report.py`, `WORK_RECORD.md` | yes | yes (Word template optional) | no - deliver the summary in chat |
| `skill_search` / `agent_search`, `capability_assessment.md` | yes | yes | by reasoning over the skill catalogue only |
| Enterprise data readers (STID, SAP, PDM, OTS, Seeq, PEPR) | with credentials | with credentials (enterprise plugin installs the packages) | no |
| Task log / PR back to NeqSim | yes | NIP + issue only | NIP in the answer |

When a row says **no**, the deliverable matrix in the agent's section 0 still
applies: do the step by the strongest available means and record what was
skipped in `results.json` `data_gaps` (or in the chat answer) so the reader knows
the evidence level.

---

## 1 ── OVERVIEW

You follow the **3-step AI-Supported Task Solving While Developing** workflow.
"While Developing" is key — solving the task and improving NeqSim happen in
the same session. The workflow is aligned with the IPA Front-End Loading (FEL)
framework and Stage-Gate methodology:

```
 STEP 1 → Scope & Research    (FEL-1: Identify)    Define standards, methods, deliverables + gather background
 STEP 2 → Analysis & Eval     (FEL-2: Evaluate)     Build simulation, run, validate, iterate until accepted
 STEP 3 → Report              (FEL-3: Define)       Generate Word + HTML deliverables
```

Each step transition is a **gate** (per Stage-Gate, Cooper 1990) — the quality
gates in Section 2 define the go/no-go criteria before advancing.

The framework also draws on:
- **AACE 18R-97** — Cost estimate classification (Class 5→1 maturity)
- **ISO 15288** — Systems engineering life cycle (needs → requirements → architecture → verification)
- **VDI 2221** — Systematic engineering design (clarify → concept → embody → detail)
- **NORSOK Z-013** — Risk and emergency preparedness (risk matrix, ALARP)
- **DNV-RP-A203** — Technology qualification (TRL assessment for novel solutions)

Your deliverable is a populated task folder under `task_solve/`.

### Post-Folder Preflight (mandatory before Step 1 work)

After the task folder exists and `user_input.md` contains the prompt, do these
checks before writing Step 1 content:

1. **Route check.** If the task spans multiple disciplines (e.g. process +
   economics + safety), invoke `@router` first to confirm which specialist
   agents to compose. For single-discipline tasks, skip.
2. **Agent & skill review (ALWAYS — thorough).** Before writing any analysis,
   do a deliberate review of the available **agents and skills** to find what
   can help solve this task instead of solving from scratch:
  - Run `<python-executable> devtools/skill_search.py "<task title>" --top 5` and load the
     top-3 SKILL.md files with `read_file`.
   - Scan the agent list (community + enterprise, e.g. `.github/agents/`,
     `neqsim-community-agents/`, `neqsim-enterprise-agents/`) for discipline
     specialists whose description matches the engineering question.
   - Record the shortlist in `step1_scope_and_research/notes.md`: which
     agents/skills you will use and why, and note explicitly where **no**
     suitable agent/skill exists (that gap is a candidate improvement in the
     Continuous Improvement Rule).
3. **NeqSim codebase review (ALWAYS).** Before writing custom code, review the
   NeqSim codebase to find existing functionality that solves the task:
   - Consult `neqsim-capability-map` and `CHANGELOG_AGENT_NOTES.md`, then use
     `semantic_search` / `grep_search` / `file_search` over
     `src/main/java/neqsim/` for the relevant classes (equipment, EOS,
     standards, mechanical design).
   - Prefer an existing NeqSim class over a simplified Python correlation.
   - Record in `notes.md` which NeqSim classes/methods will be used, and note
     any missing capability as a gap to be closed (NIP + Java implementation
     per Section 0 principle 2 and the Continuous Improvement Rule).
3b. **Data-acquisition screening (ALWAYS — before assuming stand-in data).**
   List the input data the task needs (equipment curves, geometry, fluid
   composition, operating point, etc.) and, for **each** input, screen for a
   retrieval tool/agent that can obtain the *real* value before falling back to
   a representative assumption. Do NOT proceed with stand-in data for an input
   that an available data-source agent could supply. Map each need to its
   source using this table (community names shown; use the `enterprise-` twin
   when on an enterprise task):

   | Data need | Retrieve with | Notes |
   |-----------|---------------|-------|
   | Compressor/pump curves, vendor performance maps, datasheets, P&IDs, mechanical drawings, line lists, material certs | `@stid.reader` / `stid-reader-agent` + `neqsim-stid-retriever` (STID doc download → PDF/OCR → `neqsim-technical-document-reading`) | Vendor "map"/curve docs live in STID; download then extract the map digitally |
   | Piping class, pipe internal diameter, wall thickness, valve (VDS/MDS) data, flange rating | `@tr2000` / `tr2000-agent` + `enterprise-tr2000-api` | Resolve line tag → PCS → internal Ø |
   | Live instrument data / operating point (P, T, flow, speed, valve %, current recycle) | `@plant-data` / `plant-data-agent` + `neqsim-plant-data` (tagreader PI/IP.21) or `@seeq.connect` / `enterprise-seeq-connect` | Resolve historian tag from STID tag; prefer `/PRIM` channel; check units |
   | Measured production volumes (well/field) | `rigga-production-agent` + `enterprise-rigga-production` | Measured production as feed / validation basis |
   | Equipment / maintenance / failure history | `@maintenance` / `maintenance-agent` + `enterprise-maintenance-api` | Read-only work orders, notifications |
   | Fluid composition / gas-sample molweight | STID/lab report via `@stid.reader`; else record as an explicit gap | A wrong MW mis-places compressor maps — always try to obtain it |
   | Public literature / standards | `@literature-scout` | See step 6 |

   Record in `notes.md`, for every required input: the source agent/skill you
   will use, or an explicit statement that the value is a documented **stand-in
   assumption** because no retrieval path is available (and why). "The data is a
   field unknown" is only acceptable **after** the relevant retrieval agent has
   been screened (and, where feasible, attempted). For governed enterprise
   sources (STID, TR2000, tagreader, Seeq, Rigga, Maintenance, PEPR), prefer the
   corresponding coordinator agent so authentication and read-only governance
   are handled correctly.
4. **Repo memory scan.** List `/memories/repo/*.md` via the `memory` tool.
   Read any whose filename contains a keyword from the task title — this
   surfaces prior solved tasks and known gotchas before you reinvent them.
5. **Capability assessment + agent/workflow and code discovery.** For
  Standard/Comprehensive tasks, invoke `@capability-scout` and write the result
  to `step1_scope_and_research/capability_assessment.md`. As part of this step
  you MUST run BOTH discovery tools and inspect the actual NeqSim implementation
  before selecting a method. Never rely only on the static routing table,
  capability-map prose, or mirrored task sources:

   ```bash
  <python-executable> devtools/skill_search.py "<task title>" --top 5
  <python-executable> devtools/agent_search.py "<task title>" --top 8 \
       --json --out step1_scope_and_research/agent_plan.json
   ```

     Then search `CHANGELOG_AGENT_NOTES.md`, `src/main/java/neqsim/`, neighboring
     JUnit tests, and the locally resolved NeqSim dependency/JAR for the required
     equipment, thermodynamics, standards, safety, mechanical-design, and utility
     functionality. Verify constructors, method signatures, units, limitations,
     and existing tests from source before writing analysis code. When local
     source may be stale, also check current upstream `equinor/neqsim`; do not
     classify a capability as missing from a skill description or mirrored tree
     alone.

   Then, in `capability_assessment.md`:
   - fill **§4 Skills to Load** from `skill_search.py`,
   - fill **§4b Agents to Delegate To** from `agent_search.py` (agent, repo, the
     skills it loads, and why it was picked),
   - fill **§4c Workflow Plan** — choose single-agent, a `router.agent.md`
     composition pattern, or a declarative workflow (MCP `composeWorkflow` /
     `composeMultiServerWorkflow`, or an `engineering-harness` study) when the
     task spans ≥3 disciplines. Prefer delegating to a specialist agent over
     re-loading its skills manually, so its governance and internal workflow are
     reused (this is how "all functionality gets utilized").
   - add a **NeqSim Code Functionality Reviewed** table containing each required
     capability, exact class and method signatures, source/test/JAR evidence,
     availability (`Available`/`Partial`/`Missing`), units/constraints, and how
     the task will use it.

   Persist the plan so it survives context loss and feeds the report:
   - keep `step1_scope_and_research/agent_plan.json` (raw ranking, audit trail),
   - checkpoint it via `progress.store_context("agent_workflow_plan", {...})`,
   - add an `agent_workflow_plan` object to `results.json` (see schema) and
     mention the agents/workflow used in the `approach` / `method_summary` text
     so the generated report documents *how* the task was solved.

   For Quick tasks, write a short manual capability + agent note in `notes.md`
   unless a capability gap is suspected.
6. **Literature scout** (Standard/Comprehensive only). Invoke
   `@literature-scout` to populate `step1_scope_and_research/references/`
   and the `## Literature & Reference Documents` section of `notes.md`.

### Autonomous investigation (when the symptom / cause is NOT given)

For root-cause, deviation, under-performance, trip, or "why is this happening?"
tasks where the user has **not** told you what to look for, do not ask them.
Run the investigation loop from `neqsim-autonomous-investigation` BEFORE fixing a
scope, and use **all** available data and tools, not just the one tag/unit named:

1. **Gather all data** — pull the full historian tag map (`@plant-data` /
   `neqsim-plant-data` / `@seeq.connect`), plus alarms/events, maintenance
   history, and STID design limits when available. Save snapshots to the task
   folder.
2. **Observe** — hand the whole tag map (no symptom) to
   `RootCauseAnalyzer.analyzeAutonomous(tagToEquipment)` (or MCP
   `runRootCauseAnalysis` with `symptom` omitted / `"AUTO"`). It auto-detects
   abnormal tags (`AnomalyScanner`), discovers lead-lag relationships
   (`RelationshipGraph`), and classifies them against the flowsheet topology
   (`CausalTopologyModel`).
3. **Hypothesize / test / discriminate** — form ≥3 competing hypotheses
   (including "data/instrument artifact"), verify with the NeqSim simulation, and
   report the **discovered relationships and the discriminating test**, not just a
   single conclusion. Treat any supplied classification as a hint to challenge.

For operational plant tasks involving P&ID symbols, valve actions, live plant
data, active train state, isolation, evacuation, or dynamic response, load
`neqsim-pid-process-operations` together with `neqsim-technical-document-reading`,
`neqsim-process-extraction`, `neqsim-plant-data`, `neqsim-controllability-operability`,
and `neqsim-dynamic-simulation`. Keep public outputs plant-agnostic; use private
prompt files or private skills for site-specific document sources, historian
source names, tag maps, operator procedures, and company requirements.
Use `neqsim.process.operations` for Java deliverables and MCP `runOperationalStudy`
for tool-based tag-map validation, field-data application, valve scenarios, and
controller-response metrics.
For fast liquid-hammer cases, route the extracted STID geometry, tagreader event
window, and valve closure schedule through `neqsim-water-hammer` and MCP
`runWaterHammer` before deciding whether a detailed surge study is required.

---

## 1.5 ── CONTEXT WINDOW RESILIENCE (checkpoint & resume)

Long-running tasks (Standard and Comprehensive) routinely exhaust the context
window. When this happens, the agent starts a new conversation with no memory
of previous work. The **progress checkpoint** system solves this.

### How it works

A `progress.json` file in the task folder records every completed milestone,
key decisions, derived context, and the next action. The file is updated after
each significant step. When a fresh agent picks up the task, it reads
`progress.json` first and knows exactly where to resume.

### MANDATORY: Checkpoint after every milestone

After completing each numbered step in the workflow below, write a checkpoint:

```python
import sys; sys.path.insert(0, "devtools")
from neqsim_runner.progress import TaskProgress

progress = TaskProgress("task_solve/YYYY-MM-DD_task_slug")

# After Phase 0 (classification)
progress.complete_milestone("phase0_classified",
    summary="Type B (Process), Standard scale. 3-stage compression, SRK EOS.",
    decisions={"type": "B", "scale": "Standard", "eos": "SRK",
               "task_title": "3-stage compression from 5 to 150 bara"})
progress.set_next_action("Write task_spec.md with standards and acceptance criteria")

# After Step 1 (research)
progress.complete_milestone("step1_research_done",
    summary="Research complete. Using API 617 for compressor design, "
            "NORSOK P-001 for process. Feed: rich gas, 85% methane.",
    outputs=["step1_scope_and_research/task_spec.md",
             "step1_scope_and_research/notes.md"],
    decisions={"standards": ["API 617", "NORSOK P-001"],
               "feed_composition": {"methane": 0.85, "ethane": 0.07,
                                    "propane": 0.05, "nC4": 0.03}})
progress.set_next_action("Create main notebook: 01_compression_analysis.ipynb")

# Store expensive-to-derive context
progress.store_context("api_methods", {
    "compressor_class": "neqsim.process.equipment.compressor.Compressor",
    "power_method": "getPower('kW')",
    "polytropicEff_method": "getPolytropicEfficiency()",
})
```

### MANDATORY: Check for resume on every session start

When the user asks to resume a task, check that task's `progress.json` before
doing any new work. If it exists, you are **resuming** — do NOT repeat
completed steps:

```python
import sys, os; sys.path.insert(0, "devtools")
from neqsim_runner.progress import TaskProgress

# Find the most recent task folder
import glob
tasks = sorted(glob.glob("task_solve/20*"))
if tasks:
    progress = TaskProgress(tasks[-1])
    if progress.is_resuming():
        print(progress.resume_summary())
        # READ THIS OUTPUT. It tells you:
        # - What has been done
        # - What decisions were made
        # - What to do next
        # DO NOT REDO completed milestones.
```

### What to store in checkpoints

| Milestone | What to save in `decisions` | What to save in `context` |
|-----------|---------------------------|--------------------------|
| phase0_classified | type, scale, eos, task_title | — |
| step1_spec_written | standards, acceptance_criteria | — |
| step1_research_done | feed_composition, operating_envelope | api_methods, neqsim_classes_used |
| step2_notebook_created | notebook_path, simulation_approach | cell_structure, import_patterns |
| step2_notebook_executed | key_results (T, P, power, etc.) | job_ids, output_paths |
| step2_validation_done | validation_method, max_deviation | benchmark_data_source |
| step2_results_saved | results_json_path | figure_list, table_data |
| step3_report_generated | report_paths | manual_sections_content |

### Resume rules

1. **Read progress.json FIRST for resume requests.** Before searching files or planning work.
2. **Trust completed milestones.** Don't re-validate or re-run them unless outputs are missing.
3. **Re-read decisions.** These were derived with full context — use them, don't re-derive.
4. **Check context store.** If API method names or class paths were saved, use those directly.
5. **Check for runner jobs.** If job_ids exist, check their status via the AgentBridge.
6. **Resume from next_action.** This is the exact instruction the previous agent left for you.
7. **If outputs are missing** despite milestone being marked done, re-do that milestone.

### Break large tasks into sub-conversations

For Comprehensive tasks (multi-notebook, multi-day), proactively break the work
into conversation-sized chunks. After Phase 0 + Step 1, checkpoint and tell the
user: "Step 1 is complete. Please start a new conversation and say
`@solve-task resume task_solve/YYYY-MM-DD_slug` to continue with Step 2."

### MANDATORY: Read `study_config.yaml` before planning notebooks

Every new task folder contains `study_config.yaml`. It is the explicit input
contract for task inputs, document sources, task depth, notebook plan, report
detail, and quality gates.

After creating the task folder and before writing `task_spec.md` or creating
notebooks:

1. Read `task_solve/YYYY-MM-DD_slug/study_config.yaml`.
2. Apply the intake gate before continuing:
   - If `intake.pause_after_folder_creation` is `always`, pause and ask the
     user to add or confirm missing task inputs before Step 1 work.
   - If it is `auto`, pause for Standard/Comprehensive tasks when method-critical
     values, required documents, or a fully authored config are missing.
   - If it is `never`, continue with explicit assumptions unless a missing input
     would make the calculation method invalid.
   - When pausing, tell the user the task folder path, the `study_config.yaml`
     path, and the `step1_scope_and_research/references/` drop folder. Explicitly
     say that document input is possible, including PDFs, Word files, Excel
     stream tables, P&IDs, vendor data sheets, standards, and lab reports. Do
     not create notebooks until the user confirms to continue or the required
     files are present.
3. If `study.scale`, `report.depth`, `notebooks.plan`, `inputs.documents`, or
   `quality_gates` are set to anything other than `auto`, treat those values as
   higher priority than scale inferred from the prompt.
4. If `inputs.documents_required` is true or `inputs.documents` lists source
  files, verify the files are under `step1_scope_and_research/references/`,
  classify them, extract relevant engineering data, normalize units/component
  names, validate the values, and record the extraction in Step 1 notes or
  structured JSON before building notebooks.
5. For Comprehensive / Development tasks, do not invent a notebook plan until
  `notebooks.plan` has been read. Create or execute the configured notebooks in
  order, and checkpoint after each notebook.
6. If a required configured notebook, report section, benchmark, uncertainty
  analysis, risk register, figure discussion, or consistency check cannot be
  produced, record the reason in `progress.json`, `results.json` limitations,
  and the final report.
7. Before Step 3, run `<python-executable> step3_report/generate_report.py`; the report
  generator reads `study_config.yaml` and warns about missing configured
  deliverables. Fix warnings marked as required before finalizing unless the
  user explicitly accepts the limitation.

---

## 2 ── WORKFLOW (follow this exactly)

### Phase 0: Setup — Create, Classify, and Scale

1. **Create or identify the task folder first.**

   - For a new task, the mandatory first action above has already created the
     folder using `neqsim new-task ... --prompt ...`. If not, create it now.
   - For a resume request, use the existing folder named by the user or the
     latest task folder confirmed by `progress.json`.
   - Read `README.md`, `user_input.md`, and `study_config.yaml` before writing
     Step 1 content.

2. **Confirm the task type** into one of these categories:
   - **A** — Property (density, viscosity, JT coefficient, phase envelope, etc.)
   - **B** — Process (separation, compression, dehydration, distillation, etc.)
   - **C** — PVT (CME, CVD, swelling test, saturation pressure, etc.)
   - **D** — Standards (ISO 6976, AGA, hydrocarbon dew point, etc.)
   - **E** — Feature (add new NeqSim method/equipment/model)
   - **F** — Design (wall thickness, mechanical sizing, PSV, etc.)
   - **G** — Workflow (field development, design basis, technology screening — multi-discipline)

3. **Determine the task scale** — this controls how deep you go:

| Scale | AACE Class | FEL | Indicators | Task Spec | Notebooks | Report |
|-------|-----------|-----|-----------|-----------|-----------|--------|
| **Quick** | 5 | — | Simple question, single property, one condition | Minimal (just method + acceptance) | 0-1 notebook or runner script | Brief summary only |
| **Standard** | 3–4 | FEL-1/2 | Process simulation, PVT study, single-discipline design | Full task_spec.md | 1 complete notebook | Word + HTML |
| **Comprehensive** | 1–2 | FEL-2/3 | Multiple standards cited, multi-discipline, "Class A/B study", "design basis", field development | Detailed task_spec with all sections, many standards | Multiple numbered notebooks per discipline | Full Word + HTML with navigation |

   **Scale auto-detection rules:**
   - User mentions specific standards (NORSOK, DNV, ISO) → at least Standard
   - User asks for multiple deliverables → at least Standard
   - User says "field development", "design basis", "concept selection", "Class A/B" → Comprehensive
   - User asks a single question with no standards → Quick
   - When in doubt, ask the user: "This looks like a [scale] task — should I go deeper or keep it light?"

  **Follow-up questions (ask only when method-critical data is missing):**

    Ask these scoping questions only when missing inputs would materially change
    the calculation method, acceptance criteria, or decision recommendation.
    Otherwise proceed with explicit assumptions and continue without blocking.

   1. **Fluid / resource**: What is the reservoir fluid composition? If unavailable,
      what type (lean gas, rich gas, oil, condensate)? What is the estimated
      resource volume (GIP/STOIIP) and its uncertainty range?
   2. **Operating envelope**: What are the design pressure, temperature, and flow
      rate ranges? Any constraints (backpressure limit, arrival temperature)?
   3. **Standards & jurisdiction**: Which design codes apply (NORSOK, DNV, API,
      ASME)? Which fiscal/tax regime (Norwegian NCS, UK, generic)?
   4. **Economics**: What gas/oil price range and currency? What discount rate?
      Are cost estimates needed (CAPEX breakdown, OPEX)?
   5. **Uncertainty scope**: Which parameters are most uncertain? Should Monte
      Carlo use full NeqSim process simulations (slower, more accurate) or
      simplified correlations (faster)?
   6. **Deliverables**: What output format — quick answer, notebook only, or full
      Word + HTML report? Are benchmarks against published data required?
   7. **Risk categories**: Which risk categories matter most (market, technical,
      HSE, regulatory, schedule)?

   For Quick-scale tasks, skip questions and proceed directly.

4. **If the folder still does not exist, create it now — non-negotiable:**

    ```
    Run in terminal: neqsim new-task "TASK TITLE" --type X --author "Agent" --prompt "<verbatim user request>"
    ```

    For long requests, save the prompt to a file and use `--prompt-file`.

    Use explicit depth inputs when the user requests a deep study, for example:

    ```
    neqsim new-task "TASK TITLE" --type G --author "Agent" --prompt "<verbatim user request>" --scale comprehensive --report-depth detailed --notebooks 5 --intake-pause always
    ```

    Or pass a fully authored configuration:

    ```
    neqsim new-task "TASK TITLE" --type G --author "Agent" --prompt "<verbatim user request>" --config-file path/to/study_config.yaml
    ```
   This creates `task_solve/YYYY-MM-DD_task_slug/` with all subfolders.
   **ALL subsequent files MUST go inside this folder. Do NOT proceed without it.**
   Read the generated README and verify `user_input.md` captured the prompt
   before continuing.

5. **Run the intake gate before Step 1 work:**
   - Read `study_config.yaml`.
   - Tell the user the task folder exists.
   - Ask for missing method-critical values or invite them to add documents to
     `step1_scope_and_research/references/` and edit `study_config.yaml`.
   - Explicitly say that document input is possible for the task.
   - Continue only after confirmation when `--intake-pause always` was used or
     required inputs are missing.

6. **Run the post-folder preflight** described in Section 1, then checkpoint.

   **CHECKPOINT (Phase 0):** After creating the task folder and classifying:
   ```python
   import sys; sys.path.insert(0, "devtools")
   from neqsim_runner.progress import TaskProgress
   progress = TaskProgress("task_solve/YYYY-MM-DD_task_slug")
   progress.complete_milestone("phase0_classified",
       summary="[1 sentence: type, scale, method]",
       decisions={"type": "X", "scale": "Standard", "eos": "SRK",
                  "task_title": "..."})
   progress.set_next_action("Write task_spec.md")
   ```

### Phase 1: Scope & Research (Step 1)

5. **Fill in the task specification** (`step1_scope_and_research/task_spec.md`).
   Adapt depth to the task scale:

   **Quick scale:** Fill only the essential fields — method/EOS, one-line acceptance
   criterion, and the specific condition to calculate. Leave other sections empty.

   **Standard scale:** Fill all sections — standards, methods, deliverables,
   acceptance criteria, operating envelope, input data.

   **Comprehensive scale:** Fill every section in detail. List ALL applicable
   standards with specific clause numbers. Define a complete work breakdown of
   deliverables. Set quantitative acceptance criteria for every output. Define
   the full operating envelope with min/design/max values.

   The task spec sections:

   **Design Basis Header** (Design/Development mode — per NORSOK P-001 practice):
   - **Document ID**: Auto-generated from task folder name
   - **Revision**: Rev 0 (initial), increment on significant parameter changes
   - **Status**: Draft → Issued for Review → Approved
   - **Design life**: e.g., 25 years (or N/A for property lookups)
   - **Design code**: Primary governing standard (e.g., ASME VIII Div.1, DNV-ST-F101)
   - **Design conditions**: Summary table of design P, T, flow rate with units

   **Core sections (all modes):**
   - **Applicable standards** (MANDATORY — see below): Which codes, standards, and
     company TRs govern this task (NORSOK, ISO, DNV, API, ASME, company TR documents).
     Load the `neqsim-standards-lookup` skill for equipment-to-standards mapping.
   - **Calculation methods/models**: Which EOS, correlations, pipe flow models to use
   - **Required deliverables**: What the final output must include
   - **Acceptance criteria**: Mass balance tolerance, design factors, safety margins
   - **Operating envelope**: Range of conditions to cover (P, T, flow, composition)
   - **Input data**: Reference fluid compositions, operating conditions, equipment data

   **Standards identification (MANDATORY — proportional to scale):**

   | Scale | Standards Requirement |
   |-------|---------------------|
   | Quick | 1-line note: "Per [STANDARD]" or "N/A — property lookup" |
   | Standard | Table listing each applicable standard with scope |
   | Comprehensive | Full table with clause numbers, design values, limits, compliance evidence |

   Use the equipment-to-standards mapping from `neqsim-standards-lookup` skill to
   automatically identify standards based on the equipment types in the simulation.
   Query `designdata/standards/standards_index.csv` for the mapping.

   **Scope limitations** (Design/Development mode):
   - **In scope**: What this analysis covers
   - **Out of scope**: What is explicitly excluded (e.g., "detailed fatigue analysis",
     "site-specific seismic loads", "control system design")
   - **Validity envelope**: Conditions under which results are valid (T range, P range,
     composition range, flow regime). Results outside this envelope require re-analysis.
   - **Model limitations**: Known EOS/correlation limitations at the operating conditions
     (e.g., "SRK accuracy degrades near critical point", "Beggs & Brill not validated
     above 90° inclination")

   If the user specifies standards or methods in their request (e.g., "per NORSOK P-001"),
   incorporate these directly into the task spec. If not specified, select appropriate
   standards based on the task type and engineering domain.

6. **Auto-search for similar past solutions (MANDATORY):**
   Before writing any new code, search for related prior work:
   - **Semantic search** `task_solve/` folder for keywords from the current task
   - **Keyword search** `docs/development/TASK_LOG.md` for task type, equipment, fluid, standards
   - **Search** `docs/development/CODE_PATTERNS.md` for relevant patterns
   - **Search** `src/test/java/neqsim/` for existing tests covering similar equipment/fluids
   - **Search** `examples/notebooks/` for related notebooks
   - If a similar task was solved before, **start from that solution** — adapt rather than rebuild
   - Document what prior work was found (or not found) in `notes.md`

6b. **Gather background knowledge** for the task:
   - Search the NeqSim codebase for existing classes/methods relevant to the task
   - Check `CHANGELOG_AGENT_NOTES.md` for any recent API changes affecting this task
   - Use web search if available for engineering reference data
   - **Retrieve vendor documents** if the task references specific equipment tags.
     Load the `neqsim-stid-retriever` skill for document retrieval patterns:
     relevance filtering, retrieval manifests, and backend configuration.
     If a retrieval backend is configured (via gitignored `devtools/doc_retrieval_config.yaml`),
     auto-fetch performance curves, mechanical drawings, and data sheets.
     Otherwise, expect documents in `step1_scope_and_research/references/`.
     Users can always **add documents manually** to `references/` alongside
     auto-retrieved ones — both sources coexist and are tracked in the manifest.
      Ask the user for additional documents only when the task is Standard or
      Comprehensive and the missing documents would materially change the method,
      constraints, or recommendation. For Quick tasks, proceed with documented
      assumptions unless the calculation is invalid without the document.
      For trapped-liquid fire rupture studies, load `neqsim-trapped-liquid-fire-rupture`
      and retrieve the full evidence pack before calculation: P&ID/STID isolation
      boundaries, line lists, piping specs, material certificates, flange/bolt/gasket
      data, fire-zone/PFP documents, relief/thermal relief basis, and acceptance
      criteria. Missing evidence must be written to `results.json` as assumptions/gaps.
   - **Extract figures from reference PDFs** placed in `step1_scope_and_research/references/`:
     ```bash
    <python-executable> devtools/pdf_to_figures.py step1_scope_and_research/references/ --outdir figures/
     ```
     Then use `view_image` on extracted PNGs to read engineering drawings, P&IDs,
     charts, data tables, and compressor maps. This makes PDF content available
     for AI analysis (diagram digitization, data extraction, layout understanding).

   - **Structured image analysis workflow** (for vendor drawings, P&IDs, datasheets):
     When reference documents contain engineering drawings or visual data, use the
     `neqsim-technical-document-reading` skill Section 3.7 patterns:

     1. **P&IDs** → Extract equipment tags, valve tags, instrument tags, piping
        sizes/classes, line numbers, and connection topology using the
        `PID_EXTRACTION` format. This provides the flowsheet topology that
        informs the NeqSim `ProcessSystem` model.

     2. **Vendor API datasheets** (e.g., API 692 seal datasheets, API 617
        compressor datasheets) → Extract operating conditions, design data,
        performance parameters, and material specs using the
        `VENDOR_DATASHEET_EXTRACTION` format. These values become simulation
        inputs and validation targets.

     3. **Mechanical arrangement drawings** → Extract dimensions, nozzle
        schedules, standpipe geometry (lengths, bore sizes, volumes), piping
        run lengths using `MECHANICAL_ARRANGEMENT_EXTRACTION` format. Physical
        dimensions feed into volume calculations, heat transfer models, and
        residence time estimates.

     4. **Performance maps / phase envelopes** → Digitize key points (rated
        point, surge line, cricondentherm, operating envelope boundaries)
        using `PERFORMANCE_MAP_EXTRACTION` or `PHASE_ENVELOPE_EXTRACTION`
        format. These validate simulation results against vendor/design data.

     5. **Generate figure discussions** — for each image analyzed that informs
        the engineering analysis, produce a figure discussion block (observation,
        mechanism, implication, recommendation) and include it in
        `results.json["figure_discussion"]` for the report.

7. **Write comprehensive research notes** to `step1_scope_and_research/notes.md`.
   These notes must be **substantive** — not a skeleton template.
   The depth should be proportional to the task mode.

   **Screening mode:** A condensed version covering: sources consulted, key
   data / sanity-check values, NeqSim classes used, and assumptions made.

   **Design / Development mode (full sections):**
   - **Sources** (table): Every source consulted — NeqSim classes, papers, standards,
     web references, textbooks. Minimum 5 entries for Standard tasks, 10+ for Comprehensive.
   - **Literature & Reference Documents**: For each key reference, write a structured
     summary with: file location, relevance, key equations cited, key data extracted,
     limitations, and how it applies to this specific task.
   - **Background — Engineering Context**: Explain the real-world engineering problem
     in 2-3 paragraphs. Why does this matter? What goes wrong in practice? What are
     the consequences of getting it wrong? Include industry context.
   - **Background — Physical Mechanisms**: Describe the underlying physics. What
     thermodynamic, chemical, or transport phenomena are involved? Include governing
     equations with variable definitions.
   - **Key Data / Correlations**: Reference values, design rules of thumb, typical
     operating ranges. These are the "sanity check" values used during validation.
   - **Industry Experience / Case Studies**: Known field cases, operational incidents,
     lessons learned. This grounds the analysis in reality.
   - **Relevant Standards — Detailed Requirements**: For each standard in task_spec,
     extract the specific clauses, equations, tables, and design factors that apply.
     Don't just list the standard — quote the requirement.
   - **NeqSim API Coverage — Detailed Inventory**: For each capability needed, check
     if NeqSim has it. Search the Java source code. List class names, key methods,
     and any limitations found. This feeds directly into Phase 1.5.
   - **Open Questions**: Uncertainties, missing data, things to clarify with the user

### Phase 1.5: Deep Analysis & Solution Design (required for high-consequence work)

Before writing simulation code for design, workflow, safety-critical, or
high-value economics tasks, produce a **thorough engineering analysis document**
that gives deep insight and a clear solution path. For smaller tasks, use a
condensed analysis section in notes and proceed.

7b. **Write a detailed problem analysis** to `step1_scope_and_research/analysis.md`.
    Include the following sections (depth proportional to task consequence):

    #### 7b.1 — Physics & Theory Deep-Dive
    Explain the fundamental physics/engineering behind the problem at a level
    suitable for a senior engineer review:
    - **Governing equations** with derivations or references (use LaTeX notation)
    - **Physical mechanisms** — what causes the phenomenon, why it matters
    - **Thermodynamic basis** — which EOS is appropriate and why, phase behavior
    - **Transport phenomena** — heat/mass transfer, fluid mechanics if relevant
    - **Key assumptions** — what simplifications are being made and their impact
    - **Dimensional analysis** — key dimensionless groups if applicable
    - **Order-of-magnitude estimates** — quick hand calculations to set expectations
      (e.g., "JT coefficient ~0.5 K/bar → expect ~25°C drop across 50 bar valve")

    #### 7b.2 — Alternative Solution Approaches
    List at least 2-3 different ways to solve this problem, with pros/cons:

    | Approach | Description | Pros | Cons | Recommended? |
    |----------|-------------|------|------|--------------|
    | A | ... | ... | ... | ✓ / ✗ |
    | B | ... | ... | ... | ✓ / ✗ |
    | C | ... | ... | ... | ✓ / ✗ |

    Justify the chosen approach with engineering reasoning.

    #### 7b.3 — NeqSim Capability Assessment

    **Option A (recommended for Standard/Comprehensive):** Invoke the capability
    scout agent to perform a systematic assessment:
    ```
    @capability-scout [paste the task description here]
    ```
    The scout returns a structured Capability Assessment Report covering:
    - Full capability requirements matrix with NeqSim coverage status
    - NIPs for every ❌ Missing or ⚠️ Partial gap
    - Recommended skills to load
    - Recommended agent pipeline for the task
    - Implementation priority order

    **Option B (for Quick/simple tasks):** Manually assess by checking the
    `neqsim-capability-map` skill and searching the codebase:

    | Capability Needed | NeqSim Class/Method | Status | Gap Description |
    |-------------------|---------------------|--------|------------------|
    | JT flash | ThrottlingValve | ✅ Available | — |
    | S8 solid flash | TPSolidflash | ✅ Available | — |
    | Nucleation model | — | ❌ Missing | Need CNT-based nucleation rate |
    | Corrosion rate | DeWaardMilliamsCorrosion | ⚠️ Partial | Missing S8 direct corrosion path |

    **For every ❌ Missing or ⚠️ Partial gap, write a NeqSim Improvement Proposal**
    (see Section 6 below). This is how the development flywheel turns: tasks
    surface gaps → gaps become proposals → proposals become implementations.

    #### 7b.4 — Solution Architecture
    Describe the simulation/calculation architecture:
    - **Flowsheet diagram** (text-based or markdown table showing equipment order)
    - **Data flow** — what feeds into what, what outputs are needed
    - **Iteration strategy** — recycles, adjusters, convergence approach
    - **Parametric studies** — what sensitivity sweeps to run and why
    - **Expected results** — what ranges you expect before running (from hand calcs)

    #### 7b.5 — Risk & Failure Mode Analysis
    Before building the simulation, anticipate what could go wrong:
    - **Numerical risks** — convergence failure, phase identification issues
    - **Physical risks** — conditions outside EOS validity, near-critical behavior
    - **Data risks** — missing BIPs, uncertain component properties
    - **Mitigation** — fallback approaches for each risk

    #### 7b.6 — Engineering Insight Questions
    List 5-10 engineering questions the analysis should answer. These go beyond
    "what is the answer" to "what does it mean and what should we do":
    - Example: "At what H2S level does sulfur deposition become operationally significant?"
    - Example: "Is pre-heating more cost-effective than chemical inhibition?"
    - Example: "How sensitive is the NPV to gas price vs. CAPEX uncertainty?"
    These questions drive the analysis and ensure the report provides actionable insight.

**CHECKPOINT (Phase 1 complete):** This is a natural break point. Checkpoint
before the context-heavy notebook creation and execution:
```python
progress.complete_milestone("step1_research_done",
    summary="Research complete. [key method, standards, feed comp]",
    outputs=["step1_scope_and_research/task_spec.md",
             "step1_scope_and_research/notes.md",
             "step1_scope_and_research/analysis.md"],
    decisions={"standards": [...], "feed_composition": {...},
               "simulation_approach": "...", "acceptance_criteria": {...}})
progress.store_context("neqsim_classes", {
    "main_class": "full.java.ClassName",
    "key_methods": ["method1(args)", "method2(args)"],
})
progress.set_next_action("Create analysis artifact: 01_XXXX.ipynb or run_XXXX.py with [approach]")
```
   For Comprehensive tasks, consider telling the user: "Step 1 is complete.
   Start a new conversation with `@solve-task resume task_solve/YYYY-MM-DD_slug`."

### Phase 2: Analysis & Evaluation (Step 2)

8. **Determine the right approach** (refined from Phase 1.5):
- Use the solution architecture from the analysis document
- Implement the recommended approach from the alternatives assessment
- Address each engineering insight question in the executable analysis artifact
- For every NeqSim gap: implement the proposed improvement or use a workaround
- Choose reasonable engineering defaults for missing input data (document assumptions)
- **Check for data gaps** — if analysis requires documents not yet retrieved
     (e.g., mechanical drawings, instrument datasheets, P&IDs, parallel train data):
     1. Log the gap in the notebook with what's missing and why
     2. If a retrieval backend is configured, auto-fetch the specific doc types needed
     3. If not, ask the user to drop the file in `references/` or provide the values
     4. Update the retrieval manifest with `iterative_retrievals` entries
     5. Re-extract PNGs for any new PDFs and continue analysis
     See `neqsim-stid-retriever` skill § "Iterative Retrieval During Analysis"

9. **Create the executable analysis artifact** in `step2_analysis/`:
   - For Quick tasks, a short runner script is acceptable when it gives a clearer,
     faster answer than a notebook. The script must use `neqsim_dev_setup.py`,
     write or merge `results.json`, and be executed by `neqsim_runner` or a
     direct verified command.
   - For Standard and Comprehensive tasks, create notebooks with VS Code notebook
     tools, `nbformat`, or valid `.ipynb`
     JSON. Raw JSON notebooks must be nbformat v4, keep cells in the top-level
     `cells` array, and include `metadata.language` for every cell. When editing
     existing notebooks, preserve existing `metadata.id` values.
   - Use the devtools setup pattern from `neqsim-notebook-patterns`: import
     `neqsim_dev_setup`, call `neqsim_init(project_root=PROJECT_ROOT, ...)`,
     then use classes through `ns.*` or `ns.JClass(...)`
   - Do not use `from neqsim import jneqsim` in task notebooks or runner jobs;
     that can use the installed Python package instead of workspace Java classes
   - The first setup cell must set `NEQSIM_MODE = "devtools"` and fail if the
     project root cannot be found
   - Follow the notebook structure from the `@solve-process` agent when creating
     notebooks.
   - Include clear markdown cells explaining each step in notebooks; for runner
     scripts, include concise printed output and comments only where they clarify
     non-obvious engineering logic.
   - Avoid interactive prompts, hidden kernel state, and shell-specific commands;
     every code cell must run from a fresh kernel in order
   - Load existing task-level `results.json` before adding artifact-specific
     results so multi-artifact runner merge preserves prior outputs
   - **Results & Figures (proportional requirement):**
     - Quick: at least one clear results table and at least one informative figure when visualization adds value
     - Standard/Comprehensive: detailed results tables and typically 2-3+ informative figures
     - Development/design deliverables should include enough figures to support recommendations
     - A **results section** that extracts key numerical outputs into
       a formatted table (pandas DataFrame or formatted print) with units
     - Typically **2-3+ matplotlib figures** for Standard/Comprehensive tasks showing the most important relationships
       (e.g., production profile vs time, pressure vs distance, temperature vs stage,
       cost breakdown bar chart, sensitivity tornado chart)
     - All figures saved to `figures/` as PNG with descriptive filenames
     - Figure captions added to `results.json` under `figure_captions`
     - A **summary comparison table** when comparing cases or validating against
       reference data
   - **Figure Discussion Cells** — add discussion cells for all decision-critical
     figures (and for all major figures in Design/Development mode). This is the
     critical link between calculations and conclusions. Each discussion cell should
     follow this pattern:

     ```markdown
     ### Discussion: [Figure Title]

     **Observation:** [What does the figure show? State the key finding with numbers.]

     **Physical Mechanism:** [Why does this happen? Explain the underlying physics,
     chemistry, or engineering reason.]

     **Engineering Implication:** [What does this mean for the design or operation?
     Compare against design limits, typical values, or industry experience.]

     **Recommendation:** [What action should be taken based on this result?
     Be specific: material selection, operating limits, equipment sizing, etc.]

     > *Links to: [reference specific key_results entries], answers insight question Q[N]*
     ```

     **Example figure discussion cell:**
     ```markdown
     ### Discussion: Temperature Profile Along Pipeline

     **Observation:** The gas temperature drops from 45°C at the inlet to -12°C at
     the outlet (Figure 2). The temperature crosses the sulfur deposition onset
     temperature (0°C) at approximately 12 km from the inlet.

     **Physical Mechanism:** The temperature drop is driven by Joule-Thomson cooling
     across the letdown valve (ΔT = -35°C for this gas composition at 120→45 bara)
     combined with heat loss to the 4°C seabed. The JT coefficient of 0.45°C/bar
     is typical for lean gas with 85% methane.

     **Engineering Implication:** Solid S₈ will precipitate in the pipeline between
     12 km and the outlet. The deposition rate peaks at approximately 25 km where
     the gas reaches maximum supersaturation. This represents a flow assurance risk
     requiring mitigation.

     **Recommendation:** Install direct electrical heating (DEH) between 10-30 km
     to maintain gas temperature above 5°C (with 5°C safety margin above deposition
     onset). Alternatively, pre-heat gas to minimum 60°C upstream of the valve to
     keep the entire pipeline above 0°C.

     > *Links to: outlet_temperature_C = -12°C, sulfur_deposition_onset_C = 0°C.
     > Answers insight question Q3: "At what distance does deposition begin?"*
     ```

   - **Traceability Chain** (Design/Development mode, recommended for all):
     1. **Calculation** → produces numerical results
     2. **Figure** → visualizes the results
     3. **Discussion cell** → interprets the figure (observation, mechanism, implication)
     4. **Recommendation** → specific action based on the discussion
     5. **results.json** → captures the chain in `figure_discussion` entries

     For Design/Development deliverables, every conclusion should trace back to
     specific figures and discussion cells. For Screening tasks, a brief
     interpretation paragraph after key figures is sufficient.

   - For **Type G (Workflow)** tasks: create multiple notebooks, numbered sequentially
     (e.g., `01_reservoir_fluid.ipynb`, `02_pipeline_sizing.ipynb`, etc.)

10. **Execute notebooks and runner scripts with supervised runner by default.** Fix errors immediately.

10a. **Notebook execution method — default rule (MANDATORY):**

    The default execution engine for task notebooks and scripts is `neqsim_runner`, as
    configured by `notebooks.execution_engine: neqsim_runner` in
    `study_config.yaml`. This runs notebooks in isolated subprocesses with
    their own JVMs, retry handling, persisted job state, and no manual kernel
    restart loop.

    **Use `neqsim_runner` (headless/supervised) unless `study_config.yaml`
    explicitly sets `notebooks.execution_engine: interactive`.** This is
    mandatory when ANY of these are true:
    - Standard or Comprehensive scale
    - More than one notebook
    - Parametric sweep or Monte Carlo
    - Any notebook expected to run > 5 minutes
    - Benchmark validation, uncertainty, or risk notebooks are required
    - Prior JVM crash, kernel death, hanging cell, or `RuntimeError: JVM cannot be restarted`

    **Use `run_notebook_cell` (interactive) only for quick debugging** when ALL
    of these are true:
    - `study_config.yaml` sets `notebooks.execution_engine: interactive`, or the
      user explicitly asks for interactive notebook debugging
    - Quick or Screening scale
    - Single notebook, no sweep, no Monte Carlo
    - Expected runtime < 5 minutes
    - No prior JVM/kernel crash or hanging cell in this session

    **Escalation rule:** If interactive execution hits a JVM crash, kernel death,
    hanging cell, or `RuntimeError: JVM cannot be restarted`, immediately switch
    to `neqsim_runner` for all remaining notebooks. Do not keep restarting the
    VS Code kernel and retrying interactively.

    **Runner usage:**

    ```python
    # In a standalone script or notebook orchestration cell:
    import sys; sys.path.insert(0, str(TASK_DIR.parent.parent / "devtools"))
    from neqsim_runner.agent_bridge import AgentBridge

    bridge = AgentBridge(task_dir=str(TASK_DIR))
    planned_notebooks = [
        "step2_analysis/01_analysis.ipynb",
        "step2_analysis/02_benchmark_validation.ipynb",
    ]

    # Default mode="execute" produces an executed .ipynb with all cell outputs.
    # Each run happens in an isolated subprocess with its own JVM.
    job_ids = [
        bridge.submit_notebook(notebook_path, mode="execute",
                               max_retries=3, timeout_seconds=3600)
        for notebook_path in planned_notebooks
    ]

    # Run all jobs (supervisor handles retry/recovery automatically).
    # Keep max_parallel=1 unless the task owner explicitly accepts parallel JVM load.
    bridge.run_all(max_parallel=1)

    summary = bridge.summary()
    print(summary)
    if summary["failed"] or summary["pending"]:
        raise RuntimeError("NeqSim Runner jobs did not all complete successfully")

    # Merge multi-notebook outputs instead of overwriting earlier results.
    bridge.merge_results_to_task(job_ids)

    # Get the executed notebook (only for mode="execute")
    executed_nb = bridge.get_executed_notebook(job_ids[0])
    ```

    For script-only workloads, use `bridge.submit_script()` or
    `bridge.submit_parametric_sweep()` instead of `submit_notebook()`. For
    lighter notebook jobs that do not need executed `.ipynb` outputs, set
    `mode="script"`, but keep the same success check and merge step.

    **When to use the runner vs interactive notebook:**

    | Signal | → Runner | → Interactive |
    |--------|----------|---------------|
    | Task scale | Standard / Comprehensive | Quick / Screening |
    | Notebooks in task | > 1 | 1 |
    | Monte Carlo iterations | N > 50 | N ≤ 50 or none |
    | Parametric sweep cases | > 3 | ≤ 3 or none |
    | Expected wall time | > 5 min | < 5 min |
    | Previous JVM crash this session | Always switch | N/A |
    | Need interactive debugging | No | Yes |
    | Need executed .ipynb with outputs | Yes (mode="execute") | Yes |

    The runner writes outputs to `task_dir/runner_output/` and job state to
    `task_dir/runner.db`. Use `bridge.merge_results_to_task(job_ids)` for
    multi-notebook workflows so later notebooks do not overwrite earlier
    `results.json` content. The report generator inspects `runner.db` and warns
    if planned notebooks have no successful runner job. When using
    `mode="execute"`, the original notebook is backed up and updated in place
    with cell outputs.

10b. **Equipment feasibility checks** — for any task involving compressors,
    heat exchangers, coolers, or heaters, run a Design Feasibility Report after
    the process simulation:

    ```python
    # Compressor feasibility
    CompressorFeasibility = ns.JClass(
      "neqsim.process.mechanicaldesign.compressor.CompressorDesignFeasibilityReport")
    report = CompressorFeasibility(compressor)
    report.setDriverType("gas-turbine")
    report.setCompressorType("centrifugal")
    report.generateReport()
    print("Verdict:", report.getVerdict())
    # Add to results.json:
    import json
    feasibility = json.loads(report.toJson())
    results["equipment_feasibility"] = {
        "compressor": {"verdict": feasibility["verdict"],
                       "suppliers": feasibility.get("numberOfMatchingSuppliers", 0)}
    }

    # Heat exchanger / cooler / heater feasibility
    HXFeasibility = ns.JClass(
      "neqsim.process.mechanicaldesign.heatexchanger.HeatExchangerDesignFeasibilityReport")
    hx_report = HXFeasibility(heat_exchanger)
    hx_report.setExchangerType("shell-and-tube")
    hx_report.generateReport()
    print("HX Verdict:", hx_report.getVerdict())
    ```

    Feasibility reports provide:
    - Mechanical design validation (is the machine buildable?)
    - Cost estimation (CAPEX, OPEX, 10-year lifecycle)
    - Supplier matching (which OEMs can provide this equipment?)
    - Issues and warnings (what design limits are exceeded?)

    Include feasibility verdicts in the analysis discussion and results.json.

11. **Validate results** — check all of these against the acceptance criteria in task_spec.md:
    - Are temperatures, pressures, and densities in physically reasonable ranges?
    - Does mass balance close (within tolerance from task spec)?
    - Does energy balance close?
    - Do results compare reasonably against reference data from Step 1?
    - Are there any NaN, Inf, or negative density values?
    - Are all required deliverables from task spec produced?

12. **If results fail validation**, iterate immediately:
    - Adjust fluid composition, EOS, or equipment parameters
    - Rerun the notebook
    - Document the iteration in `step2_analysis/notes.md`

   **CHECKPOINT (Phase 2 core complete):** After notebook is executed and validated:
   ```python
   progress.complete_milestone("step2_validation_done",
       summary="Main notebook executed and validated. [key results summary]",
       outputs=["step2_analysis/01_XXXX.ipynb", "figures/..."],
       decisions={"key_results": {"outlet_T_C": -18.5, "power_kW": 3500, ...},
                  "validation_passed": True, "max_deviation_pct": 2.1})
   progress.set_next_action("Create benchmark/uncertainty notebooks, save results.json")
   ```

### Benchmark Validation (required for Development; recommended for Design when benchmark data exists)

12b. Create benchmark validation evidence in one of these forms:
  - Separate notebook (`XX_benchmark_validation.ipynb`) for Standard/Comprehensive tasks
  - Section within the main notebook for Quick tasks

    Prefer the community skill `neqsim-benchmark-reference-data`
    (`equinor/neqsim-community-skills`, `skills/pvt/neqsim-benchmark-reference-data`)
    over hand-writing this block: it supplies the reference sources with their
    citation, authority tier and validated range, grades PASS/WARN/FAIL, refuses
    a reference that does not outrank the model basis, enforces the three-point
    minimum, and emits `benchmark_validation` in the shape the gate and the
    report generator expect.

    Use independent reference data when available. If no suitable benchmark
    exists, use cross-validation: hand calculations, limiting-case checks,
    conservation checks, prior NeqSim comparisons, and sensitivity sanity checks.
    The type of validation depends on the task:

     | Task Type | Benchmark Sources | What to Compare |
     |-----------|-------------------|------------------|
     | A — Property | NIST, DIPPR, experiment, literature correlations | Density, Cp, viscosity, JT coefficient at reference T,P |
     | B — Process | Published simulation cases, vendor datasheets, textbook examples | Outlet T, P, power, duty, recovery |
     | C — PVT | Lab PVT reports, ECLIPSE/PVTsim results | Saturation P, GOR, Bo, Z-factor, liquid dropout |
     | D — Standards | Standard worked examples, certified lab results | GCV, Wobbe, density to published precision |
     | E — Feature | Unit-test regression baselines, existing solver benchmarks | Convergence, residuals, iteration count |
     | F — Design | Hand calculations, vendor catalogs, published design tables | Wall thickness, weight, stress, safety factor |
     | G — Workflow | Industry benchmarks, analogous field data, public project reports | CAPEX ranges, production rates, NPV/IRR bands |

     **Benchmark notebook structure:**
     1. **Introduction** — State what is being benchmarked and why
     2. **Reference data** — Tabulate the benchmark values with source citations
     3. **NeqSim calculation** — Reproduce the same conditions and extract results
     4. **Comparison table** — Side-by-side: Benchmark vs NeqSim vs % deviation
     5. **Deviation analysis** — Plot parity chart (benchmark vs calculated), explain any deviations > 5%
     6. **Conclusion** — State whether results are within acceptable tolerance

    **Minimum requirements (when external benchmarking is used):**
     - At least 3 benchmark data points (different conditions, components, or cases)
     - A parity plot or deviation bar chart saved to `figures/`
     - A summary table with columns: Parameter | Benchmark Value | NeqSim Value | Deviation % | Source
     - Results recorded in `results.json` under `"benchmark_validation"` key

     ```python
     # Example benchmark comparison structure in results.json
     results["benchmark_validation"] = {
         "benchmark_source": "NIST Webbook / Experiment / Published case",
         "comparisons": [
             {"parameter": "density_kg_m3", "benchmark": 820.5, "neqsim": 818.3,
              "deviation_pct": 0.27, "condition": "25C, 60 bar"},
             {"parameter": "viscosity_cP", "benchmark": 0.45, "neqsim": 0.43,
              "deviation_pct": 4.4, "condition": "25C, 60 bar"},
         ],
         "max_deviation_pct": 4.4,
         "all_within_tolerance": True,
         "tolerance_pct": 5.0
     }
     ```

13. **Save figures** to `figures/` directory as PNG files. **CRITICAL: use absolute paths, NOT os.getcwd():**
    ```python
    import pathlib, os
    NOTEBOOK_DIR = pathlib.Path(globals().get(
        "__vsc_ipynb_file__", os.path.abspath("step2_analysis/notebook.ipynb")
    )).resolve().parent
    TASK_DIR = NOTEBOOK_DIR.parent
    FIGURES_DIR = TASK_DIR / "figures"
    FIGURES_DIR.mkdir(exist_ok=True)
    # Then save plots:
    fig.savefig(str(FIGURES_DIR / "my_plot.png"), dpi=150, bbox_inches="tight")
    ```
    **Figure count should be proportional to task scale and decision complexity.**
    Common figure types:
    - Process profiles (T, P, flow vs. position or time)
    - Sensitivity/parametric studies (property vs. variable)
    - Bar charts for cost breakdowns, composition, or comparisons
    - Phase envelopes, PVT curves, or equipment performance maps
    Figures must have axis labels with units, titles, legends, and grids.

14. **Write validation notes** to `step2_analysis/notes.md`:
    - What was tested and what passed
    - Comparison against reference data (quantitative where possible)
    - Whether acceptance criteria from task spec are met
    - Any sensitivity analysis performed

15. **Save results.json** in the task root folder. Add a final notebook cell:
    ```python
    import json, os, pathlib
    # Resolve task directory from the notebook's own location
    # (os.getcwd() is unreliable in VS Code notebooks — it returns workspace root)
    NOTEBOOK_DIR = pathlib.Path(globals().get(
        "__vsc_ipynb_file__", os.path.abspath("step2_analysis/notebook.ipynb")
    )).resolve().parent
    TASK_DIR = NOTEBOOK_DIR.parent
    FIGURES_DIR = TASK_DIR / "figures"
    FIGURES_DIR.mkdir(exist_ok=True)
    # ── results.json schema ──
    # TIER 1 — Always required (all modes)
    results = {
        "key_results": {
            # All key numerical outputs with units in the key name
        },
        "validation": {
            # Each check maps to True/False or a numeric value
            "mass_balance_error_pct": 0.01,
            "acceptance_criteria_met": True,
        },
        "approach": "Brief description of methodology used",
        "conclusions": "Key findings with engineering interpretation",
        "assumptions": [
            # Key engineering assumptions made during the analysis
            # {"assumption": "...", "impact": "low/medium/high",
            #  "confidence": "low/medium/high", "replace_with": "project data X"}
        ],
    }

    # TIER 2 — Populate when relevant (Design/Development or when produced)
    # The report generator renders these sections only if present;
    # missing keys are silently skipped (graceful degradation).
    #
    # results["approach_justification"] = "Why this approach was chosen..."
    # results["engineering_insights"] = {"Q1: ...": "Answer..."}
    # results["design_recommendations"] = ["Recommendation 1", ...]
    # results["neqsim_gaps"] = [{"nip_id": "NIP-01", ...}]
    # results["remaining_uncertainties"] = ["Uncertainty 1", ...]
    # results["figure_discussion"] = [{"figure": "...", "title": "...",
    #     "observation": "...", "mechanism": "...", "implication": "...",
    #     "recommendation": "...", "linked_results": [...],
    #     "insight_question_ref": "Q..."}]
    # results["figure_captions"] = {"plot.png": "Description"}
    # results["equations"] = [{"label": "...", "latex": "..."}]
    #
    # TIER 3 — Populate only when uncertainty/risk/benchmark work is performed
    # results["benchmark_validation"] = {"benchmark_source": "...", ...}
    # results["uncertainty"] = {"method": "...", "p10": ..., ...}
    # results["risk_evaluation"] = {"risks": [...], ...}
    #
    # TIER 2b — Standards compliance (MANDATORY for Standard/Comprehensive)
    # Load neqsim-standards-lookup skill for equipment-to-standards mapping.
    # results["standards_applied"] = [
    #     {"code": "NORSOK P-001 Rev 5", "scope": "Separator sizing",
    #      "status": "PASS", "design_value": 0.13,
    #      "limit": "0.12-0.15 m/s", "unit": "m/s", "clause": "Table A-1"},
    # ]
    results_path = str(TASK_DIR / "results.json")
    with open(results_path, "w") as f:
        json.dump(results, f, indent=2)
    ```

15a. **Validate results.json with TaskResultValidator (MANDATORY quality gate).**
  Add a cell immediately after saving results.json. This calls the Java validator
  programmatically to catch schema errors before proceeding to report generation.

    ```python
    # ── Programmatic quality gate: validate results.json ──
    TaskResultValidator = ns.JClass("neqsim.util.agentic.TaskResultValidator")

    with open(str(TASK_DIR / "results.json"), "r") as f:
        json_str = f.read()

    report = TaskResultValidator.validate(json_str)
    print(f"Valid: {report.isValid()}  |  Errors: {report.getErrorCount()}  |  Warnings: {report.getWarningCount()}")

    if not report.isValid():
        print("\n❌ ERRORS (must fix before proceeding to report):")
        for err in report.getErrors():
            print(f"  [{err.field}] {err.message}")

    if report.getWarningCount() > 0:
        print("\n⚠️ WARNINGS (fix for Standard/Comprehensive tasks):")
        for warn in report.getWarnings():
            print(f"  [{warn.field}] {warn.message}")

    assert report.isValid(), "results.json failed validation — fix errors above before proceeding"
    ```

  **If validation fails:** Fix the results.json contents in the cell above and re-run
  both cells. Do NOT proceed to Step 3 (report generation) with a failing validation.

### Uncertainty & Risk Analysis (conditional)

15b. Create a dedicated uncertainty/risk notebook for workflow, economics,
  reserves/resource, concept selection, or when explicitly requested.
  For smaller design/process/property tasks, uncertainty can be a compact
  section in the main notebook unless deeper treatment is needed.

     **Core principle: use NeqSim process simulations, not simplified Python models.**
     Every Monte Carlo iteration should run the same NeqSim equipment classes used
     in the main analysis. Simplified correlations are only acceptable when NeqSim
     has no equivalent class for that calculation.

     #### Uncertain Input Parameters (7–10 parameters typical)

     Always include **resource/reserve estimates** as uncertain parameters:

     | Parameter Type | Example | Distribution | Required? |
     |----------------|---------|--------------|----------|
     | Resource volume | GIP, STOIIP | Triangular or lognormal | **ALWAYS** |
     | Reservoir conditions | Pressure, temperature | Triangular | Yes |
     | Production capacity | Plateau rate, PI | Triangular | Yes |
     | Commodity price | Gas/oil price | Triangular | Yes (if economics) |
     | CAPEX | Cost multiplier | Triangular | Yes (if economics) |
     | OPEX | Annual operating cost | Triangular | Yes (if economics) |
     | Financial | Discount rate | Uniform | Optional |

     #### Monte Carlo with NeqSim

     ```python
     # CORRECT: Full NeqSim process simulation per iteration
     def run_neqsim_production(gip_volume, reservoir_pres, plateau_rate):
         fluid = SystemSrkEos(273.15 + 75.0, reservoir_pres)
         fluid.addComponent("methane", 0.90)
         # ... add components, set mixing rule
         reservoir = SimpleReservoir("res")
         reservoir.setReservoirFluid(fluid.clone(), gip_volume, 1.0, 1e7)
         well = WellFlow("well")
         pipe = PipeBeggsAndBrills("export", well.getOutletStream())
         # ... configure and run
         return gas_rate_profile, gip_gsm3

     # WRONG: Simplified Python model
     def run_simple_decline(gip_volume, plateau_rate):
         return plateau_rate * np.exp(-decline_rate * years)  # NO!
     ```

     #### Performance Optimisation Patterns

     | Pattern | How | Savings |
     |---------|-----|--------|
     | **Cache SURF cost** | Compute `base_surf = SURFCostEstimator(...)` once, scale by `capex_mult` | ~3–4 min per 200 iter |
     | **Smart tornado** | Only re-run NeqSim for technical params (GIP, Pres, Rate); reuse base profile for economic params (price, OPEX, discount) | ~50% fewer tornado runs |
     | **Bisection steps** | Use 20 steps instead of 30 for decline-phase rate search | ~30% faster per iter |
     | **Early exit** | Break production loop when rate < threshold (e.g., 0.5 MSm³/d) | Skip tail years |
     | **Seed RNG** | `np.random.seed(42)` for reproducibility | Deterministic reports |

     The community skill `neqsim-uncertainty-quantification`
     (`equinor/neqsim-community-skills`,
     `skills/process/neqsim-uncertainty-quantification`) implements these patterns
     directly: a `technical`/`economic` model split that caches the expensive
     stage (this is the "smart tornado" above), Latin-hypercube sampling,
     percentiles in the ascending `p10 ≤ p50 ≤ p90` convention the gate
     enforces, a scale-invariant convergence check, and optional SALib/chaospy
     backends for the interactions a tornado cannot see. Prefer it over
     re-implementing the loop.

    #### Minimum Simulation Count (when Monte Carlo is used)

     - **With NeqSim simulations:** N ≥ 200 (each takes ~0.5–1.0 sec)
     - **Simplified models only:** N ≥ 1000

     #### Tornado Sensitivity (Smart Classification)

     ```python
     NEQSIM_PARAMS = {"gip_volume", "reservoir_pres", "plateau_rate"}

     for param in all_params:
         if param in NEQSIM_PARAMS:
             # Re-run full NeqSim simulation with low/high value
             rate_low = run_neqsim_production(param_low, ...)
             rate_high = run_neqsim_production(param_high, ...)
         else:
             # Reuse base production profile, recalculate economics only
             rate_low = rate_high = base_rate
         npv_low = calc_npv(rate_low, economic_params_with_low)
         npv_high = calc_npv(rate_high, economic_params_with_high)
     ```

     #### Risk Register (ISO 31000 5×5 Matrix)

     Include 6–10 risks across categories: Market, Technical, Cost, Schedule, HSE,
     Regulatory. Use this risk level formula:

     ```python
     score = likelihood (1-5) × consequence (1-5)
     if score >= 17: "Very High"
     elif score >= 10: "High"
     elif score >= 5: "Medium"
     else: "Low"
     ```

     #### Results.json Schema for Uncertainty

     ```python
     results["uncertainty"] = {
         "method": "Monte Carlo with full NeqSim process simulation",
         "n_simulations": 200,
         "simulation_engine": "NeqSim (SRK EOS, SimpleReservoir, PipeBeggsAndBrills)",
         "input_parameters": [
             {"name": "GIP Volume", "unit": "m3",
              "low": 0.65e9, "base": 1.0e9, "high": 1.45e9,
              "distribution": "triangular"},
             # ... all 7-10 parameters
         ],
         "output_parameter": "NPV after tax (MNOK)",
         "p10": ..., "p50": ..., "p90": ...,
         "mean": ..., "std": ...,
         "prob_negative_pct": ...,
         "resource_estimate": {
             "gip_GSm3_p10": ..., "gip_GSm3_p50": ..., "gip_GSm3_p90": ...,
             "recovery_factor_pct_p10": ..., "recovery_factor_pct_p50": ...,
             "recovery_factor_pct_p90": ...,
             "total_production_GSm3_p10": ..., "total_production_GSm3_p50": ...,
             "total_production_GSm3_p90": ...
         },
         "capex_mnok": {"p10": ..., "p50": ..., "p90": ...},
         "tornado": [
             {"parameter": "Gas Price (0.8-2.5 NOK/Sm3)",
              "npv_low": ..., "npv_high": ..., "swing": ...},
         ]
     }
     results["risk_evaluation"] = {
         "risks": [
             {"id": "R1", "description": "...", "category": "Market",
              "likelihood": "Unlikely", "consequence": "Catastrophic",
              "risk_level": "High",
              "mitigation": "Long-term contracts, hedging"},
         ],
         "overall_risk_level": "High",
         "risk_matrix_used": "5x5 (ISO 31000)"
     }
     ```

### Quality Gate: Phase 1.5 → Phase 2

**When Phase 1.5 applies (high-consequence / Design / Development), verify:**

- [ ] `analysis.md` exists with sections populated proportionate to the task
- [ ] Physics/Theory section has governing equations and order-of-magnitude estimates
- [ ] At least 2-3 alternative approaches listed with justified selection
- [ ] NeqSim Capability Assessment table completed for every needed capability
- [ ] For material gaps: improvement noted (NIP or notes.md)
- [ ] Solution architecture described with flowsheet and expected result ranges
- [ ] 3-10 engineering insight questions (scale to task complexity)
- [ ] Research notes (`notes.md`) are substantive — not empty templates

**When Phase 1.5 is skipped (Screening mode):** verify that notes.md has
at minimum: sources consulted, key assumptions, and NeqSim classes used.

**Hold point (Design/Development mode):** Before proceeding to Phase 2,
present the user with a brief summary of: (1) chosen approach and why,
(2) key assumptions, (3) expected result ranges from hand calculations.
Ask: "Ready to proceed with simulation, or adjust the approach?"
For Screening mode, proceed without holding.

### Quality Gate: Phase 2 → Phase 3

**Core checks (all modes):**

- [ ] Every notebook cell executes without errors
- [ ] `results.json` exists with Tier 1 keys (`key_results`, `validation`, `approach`, `conclusions`, `assumptions`)
- [ ] Acceptance criteria checked — pass or documented fail
- [ ] Results table printed in notebook with units
- [ ] Some form of validation evidence documented (benchmark, hand calc, sanity check)
- [ ] Key assumptions listed in results.json `assumptions` array
- [ ] `standards_applied` populated (at minimum 1-line "Per [STANDARD]" for Quick; full table for Standard/Comprehensive)

**Additional checks (Design / Development mode):**

- [ ] Figures saved to `figures/` as PNG; `figure_captions` populated for each
- [ ] `equations` populated with key equations used
- [ ] Validation notes in `step2_analysis/notes.md`
- [ ] If benchmark notebook used: `benchmark_validation` in results.json
- [ ] If uncertainty/risk performed: `uncertainty` and `risk_evaluation` in results.json
- [ ] If resource uncertainty in scope: P10/P50/P90 in `resource_estimate`
- [ ] `figure_captions` covers figures from ALL notebooks
- [ ] Numbers consistent across notebooks (re-run all after parameter changes)
- [ ] Engineering insight questions answered in notebook and/or results.json
- [ ] Discussion cells for decision-critical figures
- [ ] `standards_applied` entries include clause numbers and design values vs limits
- [ ] `figure_discussion` populated for discussed figures
- [ ] `design_recommendations` traceable to figure discussions
- [ ] Material NeqSim gaps documented (NIPs or notes)

**If any gate fails, iterate on Step 2** — do NOT proceed to reporting with
incomplete or unvalidated results.

### Cross-Discipline Consistency Check (multi-agent / Type G tasks)

When a task involves multiple disciplines (e.g., process + mechanical + flow assurance),
verify consistency across all sub-analyses before proceeding:

- [ ] **Phase consistency:** If thermo model says 2 phases, all downstream equipment must handle 2 phases
- [ ] **Temperature consistency:** Outlet T from one unit matches inlet T of the next (within 0.1 C)
- [ ] **Pressure consistency:** Outlet P from one unit matches inlet P of the next
- [ ] **Flow rate consistency:** Mass balance across all connection points (within 0.1%)
- [ ] **Composition consistency:** Same fluid composition used across all notebooks/analyses
- [ ] **Design conditions consistency:** Mechanical design pressure/temperature envelopes cover all process scenarios
- [ ] **Standards consistency:** No contradictory requirements from different standards
- [ ] **Unit consistency:** All sub-analyses use the same unit system (SI, not mixed with Imperial)

If any inconsistency is found, resolve it before proceeding. Document the check
in `step2_analysis/notes.md` under a "Cross-Discipline Consistency" heading.

### Step 15c: Independent Check (Design/Development mode)

Before proceeding to Phase 3, perform a self-check using the "checker hat"
principle (analogous to IEC 61508 independent verification):

1. **Re-read the task_spec.md** — are all acceptance criteria addressed?
2. **Verify units consistency** — trace a key value from input through
   calculation to output. Do the units cancel correctly?
3. **Boundary check** — do results behave correctly at extreme conditions?
   (zero flow, maximum pressure, pure component)
4. **Sign/direction check** — does each result move in the physically
   expected direction when inputs change? (higher P → higher density,
   lower T → higher viscosity)
5. **Order-of-magnitude check** — compare final results against the
   hand-calculation estimates from Phase 1.5. Flag deviations > 2×.

Document the independent check in `step2_analysis/notes.md` under a
"Verification" heading. For Screening mode, items 3-4 are sufficient.

   **CHECKPOINT (Phase 2 fully complete):** After all notebooks + results.json:
   ```python
   progress.complete_milestone("step2_results_saved",
       summary="All notebooks executed. results.json saved with key_results, "
               "validation, uncertainty, risk_evaluation, figure_captions.",
       outputs=["results.json", "step2_analysis/01_XXXX.ipynb",
                "step2_analysis/02_benchmark.ipynb"],
       decisions={"results_json_complete": True,
                  "figures": ["fig1.png", "fig2.png", "fig3.png"]})
   progress.set_next_action("Generate Word + HTML report via step3_report/generate_report.py")
   ```

### Phase 3: Report (Step 3)

15d. **Analytical depth pass (MANDATORY before writing the report).**
    Everything from here on grades whether the deliverable is *well-formed*.
    This step decides whether it is *worth reading*. Apply Principle 0 of
    `neqsim-professional-reporting` — a report that restates the task, lists
    factors without ranking them, and ends in "further study is recommended"
    passes every other gate in this agent and still fails as engineering.

    Most of these moves cannot be added at write-up time, so if the analysis
    did not produce them, **go back to Phase 2 and produce them** rather than
    writing around the gap:

    1. **Rank the contributors on one common basis** — one table, one metric,
       so the candidate causes/levers are directly comparable → `contributor_ranking`
    2. **Adjudicate the source document's own recommendations** — a verdict
       (`SUPPORTED` / `SUPPORTED_WITH_CORRECTION` / `CHALLENGED`) per
       recommendation, each decided by a number → `source_recommendation_assessment`
    3. **Rule out competing hypotheses quantitatively** — with a stated margin
       and any residual caveat → `ruled_out`
    4. **Report what the source document missed** — a contributor, coupling, or
       second-order consequence not in the original scope
    5. **Test robustness and name the crossover** — where the conclusion or the
       ranking order would flip → `robustness`
    6. **State the direction of every conservatism** — each screening default
       labelled upper or lower bound on the reported quantity → `conservatism`
    7. **Name the cheapest discriminating test** — the one measurement that
       separates the surviving hypotheses, with the meaning of each outcome
       → `discriminating_test`
    8. **Report evidence that does not fit** — as a disagreement, not smoothed over
    9. **Convert qualitative asks into specifications** — a rating, purity,
       limit, or setpoint with the mechanism that sets it

    Also: hunt for the **natural experiment** already in the data (near-identical
    units on different duty, a repair that failed again, a period with a barrier
    out of service); **bound** an unmeasurable value by computing what it would
    have to be for the conclusion to change; and report any CFD/FEM/transient/
    Monte-Carlo result as validation → convergence check → result → what it does
    and does not decide (a quantity still moving with refinement is an artefact).

    Record `depth_score` in `results.json` (target 9/9 for Comprehensive or
    root-cause work, ≥ 6/9 for Standard) with a reason for each move not
    achieved. Give each conclusion its own "what remains open" instead of one
    lumped gap register at the end.

16. **Update `generate_report.py`** in `step3_report/`:
    - The report **auto-reads** `task_spec.md` and `results.json` — verify both exist
    - Fill in the executive summary with actual findings
    - Add conclusions and recommendations to `MANUAL_SECTIONS` (or rely on `results.json`)
    - Ensure all figures from `figures/` will be embedded, **including benchmark plots**
    - The Scope/Standards, Results, Discussion, and Validation sections auto-populate from data files
    - **Discussion section** auto-populates from `results.json["figure_discussion"]` —
      renders each figure's observation, mechanism, implication, and recommendation
      with traceability links. This is the core analytic content of the report.
    - If benchmark validation is performed, include a benchmark section with
      comparison table and deviation analysis from `results.json["benchmark_validation"]`
    - If uncertainty analysis is performed, include uncertainty outputs
      (P10/P50/P90, resource estimate, tornado, probability metrics)
    - If risk evaluation is performed, include a risk section with risk register
      and overall risk level from `results.json["risk_evaluation"]`

    **Report generator behaviour:**
    The `generate_report.py` template renders sections from `results.json`
    automatically. Sections with populated keys render fully; missing keys are
    silently skipped (graceful degradation). At minimum, ensure Tier 1 keys are
    present (`key_results`, `validation`, `approach`, `conclusions`, `assumptions`).
    For Design/Development tasks, also populate `figure_discussion` — it provides
    the traceability chain from results to recommendations.

    Typical section numbering for a complete report:
    0. Document Control (rev, date, status, author, checker) |
    1. Executive Summary | 2. Problem Description | 3. Scope & Standards |
    4. Approach | 5. Results | 6. Discussion | 7. Validation Summary |
    8. Benchmark Validation | 9. Uncertainty Analysis | 10. Risk Evaluation |
    11. Conclusions | 12. Assumptions Register | 13. References

    For a problem-solving / root-cause report, add the depth sections from
    step 15d after the Discussion: a **contributor ranking** table, a
    **robustness** section naming the crossover, a **ruled out** section with
    each eliminated hypothesis and its quantitative margin, and an **assessment
    of the originating document's recommendations** verdict table. Carry the
    ranking table into the executive summary — it is the result, and burying it
    in section 6 is why a reader concludes the report said nothing.

    **Document control block** (Design/Development mode — auto-populated
    from task folder metadata):
    - Document ID: `NEQSIM-{TASK_TYPE}-{DATE}-{SLUG}`
    - Revision: `Rev 0` (initial issue)
    - Date: task creation date
    - Author: from `--author` flag in `new_task.py`
    - Status: `Draft` (updated manually to `Issued for Review` / `Approved`)
    - Calculation tool: `NeqSim {version}, {EOS used}`
    - Scope limitations: from task_spec.md (in scope / out of scope / validity envelope)

    **Assumptions register** (new section 12 — Design/Development mode):
    Auto-populated from `results.json["assumptions"]`. Renders as a table:
    | # | Assumption | Impact | Confidence | Replace With |
    Each assumption is numbered and traceable to the results it affects.

    **Stale numbers trap:** MANUAL_SECTIONS text (executive_summary, conclusions)
    contains hardcoded numbers. When design parameters change (dimensions, flow rates),
    you MUST update these strings to match the latest results. Where possible, let
    conclusions come from `results.json["conclusions"]` instead of hardcoding.

17. **Run consistency checker** (MANDATORY before report generation):
    ```
    Run in terminal: <python-executable> devtools/consistency_checker.py task_solve/YYYY-MM-DD_slug/
    ```
    The consistency checker:
    - Extracts numerical values from all notebooks and results.json
    - Detects inconsistencies: numerical mismatches, scope mismatches (e.g., volumetric vs mass-based), contradictory claims
    - Produces `consistency_report.json` in the task folder
    - **Fix any CRITICAL issues before generating the report**
    - Common issue: external study data (e.g., Gudrun paper) measuring different quantities than notebook calculations — these need clarification in the report, not "fixing"

18. **Run the report generator** to produce the engineering report (Word + HTML):
    ```
    Run in terminal: <python-executable> step3_report/generate_report.py
    ```
    This is the **default and preferred output** — an engineering technical report.
    Only generate a scientific paper if the user explicitly requests it
    (`--paper` or `--paper-only`). The default workflow produces the Word and
    HTML report only.

    **File names are the report title.** A study titled "Hydrate margin for the
    export line" ships `step3_report/Hydrate_margin_for_the_export_line.docx`
    and `.html`, so the deliverable is identifiable outside its task folder. Set
    `study.title` in `study_config.yaml` (or pass `--title`) before generating.
    Files written under an earlier title are removed on regeneration — never
    leave a superseded report beside the current one.

    **Corporate Word template:** the Word report is automatically built from the
    template the user configured with `neqsim --set-report-template "PATH"`
    (or `NEQSIM_REPORT_TEMPLATE`), so it inherits their organisation's styles,
    fonts, headers, and footers. Do not pass `--no-template` or override the
    styling unless the user asks. If the generator exits with a missing-template
    error, report it — do not fall back to unbranded output silently. Tasks
    created before this support exists carry an older `generate_report.py`; copy
    `devtools/task_template/step3_report/generate_report.py` over the task copy
    to enable it.

    **Styled section formatting** (built into the template):
    - Risk Assessment: summary card with color-coded badges (High=red,
      Medium=orange, Low=green), professional table with risk levels,
      likelihood/consequence columns, and mitigation
    - Uncertainty Analysis: blue summary card, input parameters table,
      P10/P50/P90 output distribution table, tornado sensitivity table
    - Benchmark Validation: table with PASS/FAIL color coding and detail columns
    - All formatting renders automatically when corresponding keys exist in
      `results.json` — no custom rendering code needed per task

19. **Update the task README** (`README.md` in the task folder):
    - Fill in the Problem Statement
    - Check off completed steps
    - Write the Key Results section

19a. **The work record is generated with the report** (`step3_report/WORK_RECORD.md`)
    — step 18 writes it automatically. Rebuild it alone with:
    ```
    Run in terminal: neqsim work-record task_solve/YYYY-MM-DD_slug
    ```
    The report answers *what the conclusion is*; the work record answers *how it
    was produced* — every script and notebook with its purpose and outputs, every
    source system and collected document, the cached data files, the figures, an
    annotated folder map, and the commands to reproduce the study. It is built
    from the folder, so it cannot drift from the files it describes.

    **Then fill the three NARRATIVE blocks by hand** (`background`, `method`,
    `limitations`). They are the part a reader cannot reconstruct from a
    directory listing: why this approach over the alternatives, what each step
    established, which numbers are screening-level, and what evidence would
    change the answer. Text inside the blocks is preserved when the file is
    regenerated, so regenerate freely after adding scripts or data.
    Verify with `neqsim work-record <task> --check`, which fails while a
    narrative block still holds template text or a declared artifact is missing.

    **Two config keys make the auto-built half good** — set them in
    `study_config.yaml` as the analysis takes shape: `analysis.scripts`
    (file / purpose / produces) turns section 7 into the real reproduction
    sequence, and `inputs.data_sources` (system / scope / access / evidence)
    fills the source-system table with captured-vs-missing status. A one-line
    docstring on every analysis script becomes its purpose in section 3.
    Set `report.work_record: required` to make the report gate enforce it, or
    `skip` to opt out.

19b. **Pre-send review (MANDATORY — `consistency_checker.py` does not catch these).**
    A report assembled incrementally accumulates contradictions that are
    individually well-formed. Run the pre-send pass from
    `neqsim-professional-reporting`: sweep every quantity that appears more than
    once and reconcile it (or label its basis explicitly); count the items behind
    every "Three further findings"-style lead-in; list `^## ` headings and check
    for numbering gaps; re-read every "Open" / "not yet retrieved" status against
    what the study actually ended up doing; and confirm any quantity quoted on an
    alternative basis is also in `results.json`.

### Phase 4: Knowledge Capture & Contribution

20. **Identify reusable outputs**:
    - If the notebook is generally useful → mention it could go to `examples/notebooks/`
    - If a NeqSim API gap was found → document it for future development
    - If a new pattern was discovered → note it for `CODE_PATTERNS.md`

21. **Fix and improve documentation** encountered during the task:
    - If you found **errors** in existing docs (wrong API signatures, outdated
      patterns, incorrect examples), fix them and include the fixes in the PR.
    - If you discovered **missing documentation** (undocumented classes, missing
      cookbook recipes, gaps in guides), add it and include in the PR.
    - If you identified **improvements** (clearer explanations, better examples,
      additional warnings), make the changes and include in the PR.
    - Update index files (`REFERENCE_MANUAL_INDEX.md`, section `index.md`)
      when adding new doc pages.
    - Documentation fixes go in the **same PR** as the task outputs.

22. **Draft a task log entry** (but don't write to the file directly):
    - Treat `TASK_LOG.md` as public/reusable memory. Redact company/operator names,
      field/facility/asset names, equipment tag numbers, internal document names,
      private system names, access diagnostics, and task folder slugs containing
      those details. Use generic descriptors and `private task folder (redacted)`
      for confidential task outputs.
    ```
    ### YYYY-MM-DD — Task Title
    **Type:** X (TypeName)
    **Keywords:** comma, separated, search, terms
    **Solution:** task_solve/YYYY-MM-DD_task_slug/step2_analysis/notebook.ipynb
    **Notes:** Key findings, API gaps discovered, recommendations
    ```
    Show this to the user for them to add to `docs/development/TASK_LOG.md`.

23. **Create a Pull Request** (if the user asks, or if reusable outputs were produced):

    When the task produces reusable code (tests, notebooks, docs, API extensions),
    offer to create a PR. If the user confirms, execute these steps:

    ```bash
    # Create a feature branch from the current branch
    git checkout -b task/TASK_SLUG

    # Stage reusable outputs (only files that should be contributed)
    git add src/test/java/neqsim/...              # tests
    git add examples/notebooks/...                 # notebooks
    git add docs/...                               # documentation
    git add docs/development/TASK_LOG.md           # task log entry

    # Commit with descriptive message
    git commit -m "Add [description] from task: [TITLE]"

    # Push and create PR
    git push -u origin task/TASK_SLUG
    gh pr create --title "Add [description]" --body "From task-solving workflow: [TITLE]

    ## What was added
    - [list of files/features contributed]

    ## Task context
    - Task type: [X] ([TypeName])
    - Standards applied: [list]
    - Key finding: [brief summary]"
    ```

    **Important PR rules:**
    - **Never commit `task_solve/` contents** — it's gitignored for a reason.
      Only commit files copied to their proper locations (src/, examples/, docs/).
    - **Copy first, then stage** — copy notebooks to `examples/notebooks/`,
      copy tests to `src/test/java/`, etc. before `git add`.
    - **Ask before pushing** — creating a PR is visible to others. Confirm with
      the user before `git push` and `gh pr create`.
    - **One PR per task** — keep the scope focused.

---

## 3 ── TASK TYPE SPECIFIC GUIDANCE

### Type A — Property Tasks
- Use `ThermodynamicOperations` for flash calculations
- Always call `fluid.initProperties()` after flash before reading properties — `init(3)` alone does NOT initialize transport properties (viscosity, thermal conductivity will return zero)
- Compare against NIST, DIPPR, or experimental data where possible
- Plot property vs. T or P curves for validation

### Type B — Process Tasks
- Build with `ProcessSystem` — add all equipment in topological order
- Single `process.run()` after building the full flowsheet
- Check mass balance: compare inlet and outlet flow rates
- Use `@solve-process` agent patterns for notebook structure

### Type C — PVT Tasks
- Use classes from `neqsim.pvtsimulation.simulation`
- Common: `ConstantMassExpansion`, `ConstantVolumeDepletion`, `SaturationPressure`
- Plot PVT curves and compare against lab data if available

### Type D — Standards Tasks
- Use `neqsim.standards.gasquality` classes
- Verify against published standard examples/test cases
- Report all required standard outputs (GCV, NCV, Wobbe, density, etc.)

### Type E — Feature Tasks
- Search existing source code first to avoid duplication
- **Implement the Java class** with complete JavaDoc (Java 8 compatible)
- Write JUnit 5 tests that validate against known physical results
- Build with `mvnw.cmd package -DskipTests` to verify compilation
- Write a notebook showing the new feature in action
- Include a NIP documenting the design rationale

### Type F — Design Tasks
- Use `MechanicalDesign` classes where they exist
- Reference the applicable standard (ASME, DNV, API, etc.)
- Include safety factors and corrosion allowances
- Report in engineering units with clear margin-of-safety

### Type G — Workflow Tasks (Multi-Discipline)
- These are large, multi-step engineering studies (field development, design basis,
  technology screening, concept selection)
- **Step 1 (Scope) is critical** — define ALL standards, methods, and deliverables
  upfront in `task_spec.md` before any analysis
- **Create multiple notebooks** in `step2_analysis/`, numbered sequentially:
  - `01_reservoir_fluid.ipynb` — fluid characterization
  - `02_process_train.ipynb` — topside process design
  - `03_pipeline_sizing.ipynb` — pipeline hydraulics
  - `04_flow_assurance.ipynb` — hydrate, wax, corrosion assessment
  - `05_mechanical_design.ipynb` — wall thickness, sizing
  - (add/remove as needed for the specific workflow)
- Each notebook should be self-contained but reference shared fluid definitions
- **HTML report is especially valuable** for Type G — it provides a navigable,
  multi-section document linking all sub-analyses
- Consider creating a summary notebook that imports results from all sub-analyses

### Economics & NPV Calculations (applies to Type G and any task with economics)

When a task involves economic evaluation (NPV, IRR, cash flow, breakeven):

1. **Tax model must match the jurisdiction's actual law.** Do not guess tax rules:
   - **Norwegian petroleum tax**: Corporate tax (22%) and special petroleum tax (56%)
     are calculated on **independent** taxable incomes (NOT cascaded). Uplift is 5.5%/yr
     for 4 years on qualifying CAPEX. Depreciation is straight-line over 6 years.
     Loss carry-forward is per tax pool (no interest on carried losses).
   - For other jurisdictions, research the actual regime before implementing.
   - Common error: cascading taxes (applying petroleum tax to income after corporate tax)
     gives wrong effective rate. The correct marginal rate is 22% + 56% = 78%.

2. **Use component-level CAPEX, not lump-sum estimates.** For subsea field development:
   - Use `SURFCostEstimator` for field-level SURF CAPEX breakdown (Subsea, Umbilicals, Risers, Flowlines)
   - Use `SubseaCostEstimator` for individual component costs (trees, manifolds, PLETs, jumpers)
   - Use `PipeMechanicalDesignCalculator` for pipeline wall thickness and material costs
   - Report CAPEX breakdown by category with pie charts

3. **Production profile must be realistic.** Use plateau + decline model with:
   - Ramp-up period (1-2 years typical)
   - Plateau at nameplate capacity
   - Exponential or hyperbolic decline when reserves deplete
   - Recovery factor typically 40-60% for gas, 20-40% for oil (NCS)

4. **Cash flow time indexing:** Year 0 = investment year (CAPEX only, no revenue).
   Revenue starts Year 1. Do not double-count CAPEX in both the investment schedule
   and the operating cost line.

5. **Sensitivity analysis is mandatory** for economic evaluations:
   - Oil/gas price: ±20-30%
   - CAPEX: ±20%
   - Production rate: ±15%
   - Discount rate: 0%, 5%, 8%, 10%
   - Plot tornado chart or spider plot showing NPV sensitivity to each parameter

6. **Include breakeven analysis:** Calculate breakeven price (oil/gas price at NPV=0)
   using bisection or scipy optimization. Report alongside NPV and IRR.

---

## 4 ── NOTEBOOK SETUP PATTERN

See the `neqsim-notebook-patterns` skill for the complete devtools setup cell,
`ns.*`/`ns.JClass(...)` import patterns, and notebook structure template.

### Loading Custom Java Classes in Notebooks

When using newly created NeqSim Java classes from Python notebooks, do not rely
on the installed Python `neqsim` package. Use the task setup cell to load local
workspace classes, then resolve additional classes through `ns.JClass(...)`:

```python
MyClass = ns.JClass("neqsim.process.mechanicaldesign.subsea.SURFCostEstimator")
```

**Common classpath issues:**
- Old JAR versions in Python site-packages can shadow workspace changes when using `jneqsim`
- Task notebooks should call `neqsim_init(project_root=PROJECT_ROOT, recompile=False, ...)`
- Use `ns.JClass()` for explicit class loading when `neqsim_classes(ns)` does not preload the class

---

## 5 ── DELEGATE TO SPECIALIST AGENTS

For complex sub-tasks within your workflow, you may delegate to specialist agents:

| Sub-task | Agent | When to use |
|----------|-------|-------------|
| Fluid setup | `@thermo-fluid` | Complex oil characterization, CPA systems |
| Process simulation | `@solve-process` | Large flowsheets with recycles/adjusters |
| PVT experiments | `@pvt-simulation` | Multi-point PVT studies |
| Gas quality | `@gas-quality` | ISO 6976, AGA calculations |
| Mechanical design | `@mechanical-design` | Wall thickness, vessel sizing |
| Flow assurance | `@flow-assurance` | Hydrate curves, wax, corrosion |
| Safety | `@safety-depressuring` | Blowdown, PSV sizing |
| Field development | `@field-development` | Concept selection, subsea tieback, NPV/IRR, production forecasting |
| Document / image reading | `@read technical documents` | Extract data from PDFs, vendor datasheets, P&IDs, mechanical drawings, performance maps, API datasheets |

You don't have to delegate — you can handle everything yourself. But for deep
specialist work, the dedicated agents have more detailed instructions.

For **Type G (Workflow)** tasks, you will likely need multiple specialist agents
in sequence. Coordinate them through the task_spec.md requirements.

---

## 6 ── NEQSIM IMPROVEMENT PROPOSALS (when material gaps are found)

When capability assessment identifies material NeqSim gaps (❌ Missing or ⚠️ Partial),
write concrete improvement proposals. Use proportionality:

- Required for Development mode and high-impact Design/Workflow tasks
- Recommended for recurring or high-value gaps
- Optional for one-off low-impact gaps (document limitation and workaround in notes)

### 6.1 — When to Write Proposals

Write a NeqSim Improvement Proposal (NIP) when the gap:
- Blocked or limited the analysis quality
- Required a Python workaround that should be in Java
- Would make future similar tasks significantly easier
- Represents a commonly needed engineering capability

Proposals go into `step1_scope_and_research/neqsim_improvements.md`.

### 6.2 — Proposal Structure (for each gap)

```markdown
### NIP-XX: [Short Title]

**Gap:** [What NeqSim cannot do today]
**Impact on task:** [How this limited the current analysis]
**Priority:** Critical / High / Medium / Low

#### Proposed Implementation

**Package:** `neqsim.process.equipment.[package]` (or `thermo`, `pvtsimulation`, etc.)
**Class name:** `ProposedClassName`
**Extends:** `[BaseClass]`

**Key methods:**
| Method | Parameters | Returns | Description |
|--------|-----------|---------|-------------|
| `calculate()` | — | void | Main calculation |
| `getResult()` | String unit | double | Primary output |

**Constructor:**
```java
public ProposedClassName(String name, StreamInterface inletStream) {
    super(name, inletStream);
}
```

**Governing equations:**
$$ [key equation in LaTeX] $$

**Standards implemented:** [e.g., API 520 Section 4.3, DNV-OS-F101 Sec. 5]

**Test case:**
```java
@Test
void testBasicCase() {
    // Describe what the test should verify
    // Expected output: [value] ± [tolerance]
}
```

**Estimated complexity:** Small (1-2 days) / Medium (3-5 days) / Large (1-2 weeks)
```

### 6.3 — Implementation During Task (MANDATORY, not optional)

A gap that blocked or slowed THIS task is closed in THIS task. Deferring it to a
proposal is only acceptable when the fix is genuinely larger than the task
itself — and then the NIP must say why.

For a NeqSim gap:

1. **Implement the Java class** under the appropriate package (Java 8 only)
2. **Write complete JavaDoc** (per MANDATORY requirements)
3. **Add a JUnit 5 test** with physical validation
4. **Format**: `./mvnw spotless:apply` (Windows: `mvnw.cmd spotless:apply`), then verify `./mvnw test -Dtest=...`. CI runs `spotless:check` and fails on any unformatted file; use the wrapper, never bare `mvn`.
5. **Use the new class** in the task notebook — a class nothing calls is not evidence
6. **Include in the PR** as a NeqSim contribution before the task closes

For an agent or skill gap (a wrong/missing API recipe, an undocumented gotcha, a
missing hand-off between two skills, a useful new composition): edit the
`SKILL.md` / `*.agent.md` in the right repo — community content stays
plant-agnostic, site-specific detail goes to the enterprise repos — and update
the "Loaded skills" / router guidance if the pipeline changed.

Then record it in **both** places, every task:

- `step1_scope_and_research/neqsim_improvements.md` → section 1 "Delivered"
- `results.json` → `improvements` array, e.g.

```json
"improvements": [
  {"target": "neqsim",
   "gap": "no way to turn a field seat-leak test into a leak rate",
   "change": "added neqsim.process.diagnostics.ValveSeatLeakageAssessment",
   "evidence": "ValveSeatLeakageAssessmentTest, 6 tests green"}
]
```

If nothing needed changing, say so explicitly — `validate_task_results.py`
warns on a silent record, because silence means the question was never asked.
Never ask the user for permission to do this step.

This turns every task into a potential NeqSim enhancement — the development
flywheel: **task → gap → implementation → better next task**.

### 6.4 — Workaround Documentation

When a NeqSim gap cannot be implemented during the task, document the
Python workaround used AND why the Java implementation would be better:

```markdown
#### Workaround Used
```python
# Python workaround for missing CNT nucleation model
def estimate_nucleation_rate(supersaturation, temperature):
    # Classical Nucleation Theory — simplified
    J = A * exp(-16*pi*sigma**3*v**2 / (3*kT**3 * (ln(S))**2))
    return J
```

#### Why Java Implementation Is Better
- Accessible from all notebooks without copy-paste
- Integrated with NeqSim thermodynamics (no manual property lookups)
- Can use NeqSim's fugacity coefficients directly
- Testable with JUnit, maintained as part of the codebase
```

---

## 7 ── ENGINEERING INTERPRETATION IN REPORTS

Reports should go beyond presenting numbers — they should provide **engineering
insight and actionable recommendations**. The depth of interpretation should be
proportional to the task mode: Screening tasks need brief context; Design and
Development deliverables need full interpretation with traceability.

### 7.1 — Results Interpretation Requirements

For every key result, the report must include:

1. **The number** — what was calculated, with units and uncertainty
2. **The context** — how does this compare to typical values, design limits, or
   industry experience?
3. **The implication** — what does this mean for the engineering decision?
4. **The recommendation** — what should the engineer do based on this result?

**Example (bad — numbers only):**
> The JT outlet temperature is -20.8°C. The corrosion rate is 0.037 mm/yr.

**Example (good — with engineering interpretation):**
> The JT outlet temperature of -20.8°C is well below the sulfur deposition
> onset temperature (0°C), confirming that S8 desublimation will occur across
> the letdown valve under all operating scenarios. This temperature is also
> below the MDMT (-29°C for carbon steel per ASME B31.3 Table A-1), so material
> selection must account for low-temperature service.
>
> The combined corrosion rate of 0.037 mm/yr (CO2 + H2S + S8 mechanisms) is
> classified as "Low" per NORSOK M-001 Table A.1 (<0.1 mm/yr). However, the
> presence of non-protective mackinawite FeS at this temperature means the
> rate may accelerate under high-velocity or two-phase conditions. **Recommendation:**
> specify CRA material (22Cr duplex) for the first 3 pipe diameters downstream
> of the valve, and carbon steel with 3 mm corrosion allowance beyond.

### 7.2 — Conclusions Should Be Actionable

For Design/Development deliverables, the conclusions section should contain:
1. **Summary of key findings** — 3-5 bullet points with numbers
2. **Engineering recommendations** — specific, actionable advice
3. **Design implications** — what parameters should be used in detailed design
4. **Remaining uncertainties** — what the analysis could not resolve
5. **Suggested follow-up** — next steps, additional studies needed

### 7.3 — Figure-by-Figure Discussion (Traceability Chain)

For Design/Development deliverables, decision-critical figures should have a
corresponding discussion that creates a traceable chain from calculation
to recommendation. For Screening tasks, brief inline comments suffice:

```
Calculation → Figure → Discussion → Conclusion → Recommendation
     ↓           ↓          ↓            ↓              ↓
  results.json  figures/  figure_discussion  conclusions  design_recommendations
```

#### In the Notebook

After decision-critical figure cells, add a **markdown discussion cell** with:
1. **Observation** — what the figure shows (with numbers)
2. **Physical Mechanism** — why it happens
3. **Engineering Implication** — what it means for design/operation
4. **Recommendation** — specific action to take
5. **Traceability** — which results.json entries and insight questions this addresses

(See Section 2 step 9 for the full template and example.)

#### In results.json

Populate the `figure_discussion` array — schema shown in the results.json
template (Section 2, step 15, Tier 2).

#### In the Report

The report generator auto-renders `figure_discussion` entries as a structured
"Discussion" section between Results and Validation.

#### Quality Check (Design / Development mode)

- Decision-critical figures should have matching entries in `figure_discussion`
- `design_recommendations` entries should trace back to figure discussions

### 7.4 — Report Section Enhancement

Add these sections to the report (in `generate_report.py` MANUAL_SECTIONS):

- **Engineering Context**: Why this analysis matters, what problem it solves,
  consequences of the wrong answer (1-2 paragraphs)
- **Solution Approach Justification**: Why the chosen method/EOS/model is
  appropriate — with reference to alternatives considered in Phase 1.5
- **Results Discussion**: Auto-populated from `figure_discussion` entries —
  shows observation, mechanism, implication, and recommendation for each figure
- **Design Recommendations**: Specific actionable recommendations with
  reference values, material selections, operating limits
- **NeqSim Capabilities & Gaps**: Summary of what NeqSim enabled, what
  workarounds were needed, and proposed improvements (from NIPs)

---

## 8 ── CRITICAL RULES

0. **NeqSim API first.** Every thermodynamic property, flash calculation, process simulation, and equipment sizing must use NeqSim Java classes (via `neqsim_dev_setup.py`/`ns.*` in task notebooks, runner scripts, or JUnit tests). Never substitute a simplified Python correlation, regression, or hand-formula when a NeqSim class exists for the same calculation. Search the Java source first. If no class exists, that is a gap — see Rule 21.
1. **Create the `task_solve/` folder FIRST for new tasks — this is non-negotiable.** Always run `neqsim new-task "TITLE" --type X --author "Agent" --prompt "<verbatim user request>"` before writing any files. For resume requests, read the existing task's `progress.json` first instead of creating a duplicate. ALL deliverables (task_spec.md, executable calculations, notes.md, results.json, figures/) MUST be placed inside the generated `task_solve/YYYY-MM-DD_task_slug/` folder. Never write analysis files to the workspace root, `examples/`, or any other location. If the folder was not created for a new task, STOP and create it now.
2. **Scale to the task.** Quick tasks get minimal ceremony. Comprehensive tasks get full documentation. Don't over-engineer a simple property lookup or under-deliver a field development study.
3. **Fill in the task spec.** Standards, methods, and deliverables must be defined in `task_spec.md` before analysis. For Quick scale, only essential fields.
4. **Deep analysis before code (when applicable).** For high-consequence Design/Development tasks, write `analysis.md` before coding. For Screening tasks, a condensed analysis in notes.md is sufficient.
5. **Run every executable artifact.** Do not deliver unexecuted notebooks or untested runner scripts. Fix errors immediately.
6. **Verify physics.** Mass balance, energy balance, reasonable ranges. Flag anything suspicious.
7. **Check acceptance criteria.** Results must meet the criteria defined in `task_spec.md`.
8. **Document assumptions.** Every engineering default you choose must be stated explicitly.
9. **Save figures.** All plots go to `figures/` as PNG for reports. **NEVER use `os.getcwd()` or `pathlib.Path.cwd()` to resolve figure paths** — VS Code notebooks set cwd to the workspace root, not the notebook directory. Always use the absolute path pattern from the notebook template.
10. **Write all required notes.** Research notes, analysis documents, and validation notes required by the selected scale must be populated — not left as templates.
11. **API verification.** If unsure about a NeqSim method, search the Java source to confirm it exists. Do NOT guess method names.
12. **Doc code verification.** When producing code that will appear in documentation or examples, write a JUnit test (append to `DocExamplesCompilationTest.java`) that exercises every API call shown, and run it to confirm it passes. See `neqsim-api-patterns` skill.
13. **Verify every formula against domain standards.** Do not assume a formula from memory is correct — look up the governing equation in the applicable standard or textbook. Common errors: cascaded vs independent tax bases, missing terms (uplift, depreciation), wrong operator precedence in compound expressions. After implementing, verify with a manual hand-calculation for at least one data point.
14. **Use NeqSim Java classes for cost/design — never flat estimates.** When CAPEX or mechanical design values are needed, search for existing classes in `neqsim.process.mechanicaldesign` (e.g., `SubseaCostEstimator`, `SURFCostEstimator`, `PipeMechanicalDesignCalculator`). Use component-level estimates, not a single lump-sum number. If a needed class doesn't exist, implement it with proper JavaDoc and unit tests before using it in notebooks or runner scripts.
15. **Cross-check results against industry benchmarks.** Every key output should be sanity-checked: typical SURF costs are 40-60% of total field development CAPEX; Norwegian petroleum tax is ~78% marginal; subsea tree costs are $5-15M; pipeline costs for NCS are $1,500-5,000/m. If results diverge significantly from benchmarks, investigate before accepting.
16. **Currency and unit conversions must be explicit and parameterized.** Never hardcode exchange rates inside formulas. Define them as named variables (e.g., `USD_TO_NOK = 10.5`) at the top of the notebook and reference throughout. State the assumed rate in `results.json` and report text.
17. **Notebooks used for teaching must have theory cells.** When the task has educational value, include: (a) governing equations with LaTeX rendering, (b) explanation of why each parameter matters, (c) 2-3 exercises for the reader, (d) academic references. This applies especially to Type G workflow tasks.
18. **After first draft, always self-review calculations.** Before delivering, re-read every formula cell and check: correct signs (revenue positive, cost negative in cash flow), no double-counting (CAPEX in both investment and operating cost), correct time indexing (year-0 vs year-1), tax model matches the jurisdiction's actual law.
19. **Units matter.** Kelvin for constructors, unit strings for setters. Always state units in output.
20. **No `pip install neqsim` for local task notebooks or runner scripts.** Use `neqsim_dev_setup.py` and `ns.*`/`ns.JClass(...)` so runner jobs use workspace Java classes.
21. **Extend NeqSim when gaps are found.** When a task needs a capability NeqSim lacks, don't just work around it — write a NIP in `neqsim_improvements.md`, and when feasible within the session, implement the new Java class with complete JavaDoc and JUnit tests. This is a primary output of the agent, not a side activity. For minor one-off gaps, document the limitation and Python workaround used.
22. **Engineering interpretation matters.** Reports should explain what results mean, not just what the numbers are. In Design/Development mode, every key result needs context, implication, and recommendation. In Screening mode, brief interpretation of key findings is sufficient.
23. **Answer the insight questions.** When Phase 1.5 was performed, engineering insight questions should be explicitly answered in the report conclusions.
24. **Discuss key figures proportionately.** Provide discussion cells for all decision-critical figures, and for all figures in Design/Development mode deliverables. Populate `figure_discussion` accordingly.
25. **Traceability supports credibility.** In Design/Development mode, design recommendations should trace back through: recommendation ← figure discussion ← figure ← calculation ← results.json. For Screening, direct citation of key results is sufficient.
26. **PR safety.** Never commit `task_solve/` contents. Copy reusable files to proper locations first. Always ask before `git push`.
27. **Management of Change.** When the user requests a parameter change mid-task
    (dimensions, flow rate, composition, EOS), document the change in
    `step2_analysis/notes.md` under a \"Changes\" heading (what changed, why,
    impact on prior results). Then re-run all affected notebooks in order
    and update `results.json`, figures, and report text. Increment the
    revision in the Design Basis Header if one exists.

---

## 9 ── DELIVERING THE TASK

After completing all phases, present an executive summary to the user.
The delivery message should read like a **consultant's briefing note** —
the reader should understand the problem, the approach, the answer, and what
to do next, without opening any files.

**Required elements (all modes):**

1. **Task folder**: `task_solve/YYYY-MM-DD_task_slug/`
2. **Task scale**: Quick / Standard / Comprehensive (with rationale)
3. **Engineering answer**: 3-5 sentences answering the core engineering question
   with specific numbers, context, and recommendations
4. **Key results table**: Critical outputs with units
5. **Deliverables produced**: List of populated files (task_spec, notebooks,
   results.json, reports)
6. **Standards applied**: Governing codes and methods used

**Additional elements (Design / Development mode):**

7. **Design recommendations**: Specific actionable engineering advice
8. **Remaining uncertainties**: What the analysis could not resolve
9. **NeqSim gaps**: Summary of NIPs or workarounds used
10. **Suggested next steps**: promote notebook, implement NIPs, log the task
11. **Task log entry**: Draft entry for `TASK_LOG.md`
12. **PR opportunity**: Offer to contribute reusable outputs back to the repo

---

## 10 ── LESSONS LEARNED (from solved tasks)

These are practical pitfalls discovered while solving real engineering tasks.
Review before starting any Standard or Comprehensive task.

### 10.1 Report Generator Pitfalls

L1. **The `generate_report.py` template now includes built-in styled formatting**
   for Benchmark Validation, Uncertainty Analysis, and Risk Evaluation sections.
   These render automatically when the corresponding keys exist in `results.json`
   (`benchmark_validation`, `uncertainty`, `risk_evaluation`). You do NOT need to
   add custom rendering logic per task — just populate the results.json correctly.
   The formatters produce color-coded risk badges, P10/P50/P90 tables, tornado
   tables, and PASS/FAIL benchmark tables in all four outputs (the Word and HTML
   report — and the Word/HTML paper when `--paper` is used).

L2. **Four layers must stay synchronised for every report section:**
   - `build_sections()` — defines the section with heading, content, and flags
   - `build_word_report()` — renders Word-specific content (tables, figures)
   - `build_html_report()` — renders HTML-specific content (styled tables, base64 images)
   - `build_paper_docx()` / `build_paper_html()` — paper equivalents (only used with `--paper`)
   The template has these pre-wired for standard section types. Only add
   custom handling if you need task-specific rendering beyond the built-in formatters.
   If any one layer is missing, that section will render as plain text or be blank.
   **Default output is report only** — do not generate papers unless the user asks.

L3. **Hardcoded numbers in MANUAL_SECTIONS go stale.** When equipment dimensions,
   flow rates, or other design parameters change during iterative design, the
   executive summary and conclusions text must be updated manually. The report
   generator does not auto-update these strings from results.json.
   **Best practice:** Write conclusions in `results.json["conclusions"]` and let
   the generator read from there. Only use MANUAL_SECTIONS as a fallback.

L4. **Figure captions must cover ALL notebooks.** Each notebook (main analysis,
   benchmark validation, uncertainty/risk) generates its own figures. All figure
   filenames must appear in `results.json["figure_captions"]`, otherwise the
   report shows generic captions like "Figure 10: benchmark_ntu_validation.png".

### 10.2 Multi-Notebook Coordination

L5. **Design parameter changes cascade across all notebooks.** If the user requests
   a design change (e.g., vessel dimensions, flow rate), you must re-run ALL
   notebooks in order, since benchmark and uncertainty results depend on the
   base case. Re-running only the main notebook leaves stale results in the
   benchmark and uncertainty notebooks.

L6. **Each notebook should save its portion of results.json independently.**
   The main notebook writes `key_results`, `validation`, and main `figure_captions`.
   The benchmark notebook appends `benchmark_validation`.
   The uncertainty notebook appends `uncertainty` and `risk_evaluation`.
   This avoids a single monolithic save cell that can't be run from any notebook.

L7. **Notebook kernel must be restarted before re-running.** When NeqSim classes
   are loaded via JPype, stale Java object state can persist between runs.
   Always restart the kernel before a full re-execution.

### 10.3 Figure Management

L8. **Use descriptive filenames with notebook prefix.** Files like `fig1_xxx.png`
   are for the main notebook; `benchmark_xxx.png` for benchmarks;
   `uncertainty_xxx.png` and `risk_matrix.png` for uncertainty/risk. This makes
   it clear which section each figure belongs to.

L9. **Embed section-specific figures in their own section.** Don't dump all 12
   figures after the Results section. Benchmark figures should appear in the
   Benchmark Validation section, uncertainty figures in Uncertainty Analysis, etc.
   The report generator should check section flags (`has_benchmark`,
   `has_uncertainty`, `has_risk`) and embed the right subset of figures.

### 10.4 Iterative Design Workflow

L10. **Expect at least one design iteration.** The first simulation run rarely
    gives optimal results. Budget time for changing key parameters (bed size,
    vessel diameter, number of stages) and re-running. Document the rationale
    for each iteration in `step2_analysis/notes.md`.

L11. **Sensitivity analysis reveals the right parameters to iterate on.** Run the
    Monte Carlo / tornado analysis early — it tells you which parameters dominate
    the outcome. Focus design iterations on the high-swing parameters.

### 10.5 Results.json Best Practices

L12. **Keep key_results flat and machine-readable.** Use descriptive key names with
    unit suffixes: `pressure_drop_mbar`, `bed_lifetime_years`, `wall_thickness_mm`.
    These suffixes enable automatic unit detection in the report renderer.

L13. **Include a `tables` array for structured data.** Complex comparison tables
    (literature validation, strategy comparison, cost breakdown) should go into
    `results.json["tables"]` with headers and rows, not just as text in conclusions.

L14. **Tornado data should be sorted by swing.** When writing tornado results to
    results.json, store all parameters even those with zero swing. The renderer
    should sort by swing magnitude for the tornado chart.