# POSIX Emission

## Why This Exists

The IR is designed around a POSIX sh target, not bash source generation. Emitters need argument boundaries, type information, source maps, graph metadata, decorators, and safety decisions to produce standalone scripts that run without the Shellops authoring runtime.

## Producers

- **Resolver:** provides validated graph, env surface, safety gates, hooks, and operation metadata.
- **Emitter:** consumes IR and writes root scripts, group scripts, standalone `scripts = {}` outputs, drill files, and shared `.opcache` helpers.

## Consumers

- **Generated POSIX scripts:** use embedded metadata for runtime errors and help text.
- **Drilling:** executes the same emitted artifacts used by standalone script generation.
- **CI/release artifacts:** run without the original Shellops workspace being present.

## Emission Inputs

```json
{
  "role": "pipeline",
  "name": "release",
  "payload": [
    {
      "role": "call",
      "payload": [
        { "role": "target", "payload": "deploy" },
        { "role": "args", "payload": [
          { "role": "named", "name": "version", "payload": [{ "role": "var", "payload": "VERSION" }] }
        ]},
        { "role": "source", "payload": "#/sourcemap/pipelines.release.0" }
      ]
    }
  ]
}
```

In OPX:

```
Pl01_ 0.pipeline
nPl01 1.name:string."release"
cP01_ 1.call
tCl01 2.target:string."deploy"
aCl01 2.args
nAr01 3.named
nnA01 4.name:string."version"
vnA01 4.var:string."VERSION"
sCl01 2.source:string."#/sourcemap/pipelines.release.0"
```

The sourcemap entry for this step:

```json
{
  "role": "node",
  "name": "pipelines.release.0",
  "payload": [
    { "role": "source", "payload": "file:ci.ops" },
    {
      "role": "span",
      "payload": [
        { "role": "start", "payload": [8, 3, 118] },
        { "role": "end", "payload": [8, 35, 150] }
      ]
    }
  ]
}
```

In OPX:

```
Nd01_ 0.node
nNd01 1.name:string."pipelines.release.0"
sNd01 1.source:string."file:ci.ops"
spN01 1.span
stSp1 2.start
s1St1 3.item:int.8
s2St1 3.item:int.3
s3St1 3.item:int.118
enSp1 2.end
e1En1 3.item:int.8
e2En1 3.item:int.35
e3En1 3.item:int.150
```

## Emission Rules

- Preserve invocation argument boundaries; never rebuild args by splitting strings.
- Use type-aware flattening for known structured outputs.
- Use `__json.awk` only for opaque JSON and untyped capture access.
- Use function-name-prefixed variable mangling instead of `local`.
- Emit skip checks from resolved skip metadata rather than re-deriving safety/dependency policy from syntax.
- Embed enough source-map metadata for runtime diagnostics without requiring source files on disk.
- Inline or package runtime shims needed by standalone scripts.

## Generation Contributors

POSIX generation uses a dispatch model that mirrors the IR's own structure. The core emitter owns traversal, ordering, shell hygiene, source-map embedding, and final script assembly. Focused generation contributors declare the IR roles they understand and return POSIX fragments or metadata contributions.

The dispatch follows the same two-case pattern as the IR itself:

```
emit(node) → lookup_contributor(node.role)(node.payload)
```

Leaf payloads emit directly (quoted strings, numbers). Composite payloads iterate their items and dispatch to sub-contributors by role. This uniformity is what makes higher-order generator patterns possible — contributors compose, wrap, and chain because they all share the same input contract.

Examples:

- A **call contributor** receives a call's payload, queries for `target` and `args` roles, and renders a POSIX invocation with preserved argument boundaries.
- A **need contributor** emits prereq dispatch and skip propagation for `need` roles.
- A **safety contributor** emits `--allow-remote` / `--allow-dangerous` gates from `safety` roles.
- A **export/capture contributor** emits binding wiring for `export` and `capture` roles.
- A **branch contributor** renders conditional, failure-handling, and match branches by iterating clause payloads.

This gives registry-driven language growth a place to plug in: new op.sh registration features can lower into new roles, then add focused generation contributors for those roles. The IR stays data-first; extensions contribute generation behavior, not arbitrary script mutations.

## Source Map Strategy

POSIX scripts should embed a compact map from generated function/step labels back to IR source IDs and spans. If source content is embedded in the IR, standalone scripts can include snippets directly. If only package provenance is available, diagnostics should report package, version, path, digest, and span.

The map should include enough information to call the POSIX `opx_error` formatter with the same data the Rust compiler would have: error key/code, message/help, source ID, span, source snippet or package provenance, and any structured context. That also gives non-error benefits: drill-file provenance, generated-code debugging, cache invalidation, audit trails for standalone scripts, and machine-readable CI annotations.

## Smoke Test

Before treating the schema as stable implementation ground, add a tiny pre-v1 POSIX emission smoke test. A useful slice is one file with an env entry, one pipeline, one call, one `need` dependency, one `export` binding, and one branch. If that subset cannot generate understandable POSIX with useful source-mapped diagnostics, revise the IR before broadening implementation.

## Invariants

- Emitted scripts target POSIX sh / dash.
- No bash-only constructs: no `local`, `[[ ]]`, associative arrays, namerefs, `compgen`, or `@`-prefixed runtime functions.
- Generated artifacts do not depend on the Shellops authoring runtime.
- Drilling and standalone `scripts = {}` use the same emitted code path.
- Raw secrets never appear in emitted scripts through IR defaults or source maps.

## Design References

- [architecture](../architecture.md) defines the POSIX target and JSON handling strategies.
- [build_tiers](../build_tiers.md) tiers 16-21 define the emitter, shim, drill files, scripts, and build flow.
- [drilling](../drilling.md) defines `.opcache`, help, skip behavior, and drill artifacts.
- [sources-and-provenance](./sources-and-provenance.md) defines source-map requirements.
