Repository: UKGovernmentBEIS/inspect_ai
Issue: Improve structure and typing of sandbox environment objects

The function that resolves a sandbox environment is:

```python
def resolve_sandbox_for_task(
    task: Task,
    sample: Sample,
) -> tuple[str, str | None, str] | None:
    sandbox = resolve_sandbox(task.sandbox, sample)
    if sandbox is not None:
        return sandbox + (task_run_dir(task),)
    else:
        return None
```

This function returns a sandbox environment as a `tuple[str, str | None, str]` without any names for the fields. 

As far as I can tell: 

- sandboxenv[0]: `local` or `docker`
- sandboxenv[1]: string path to an optional config file (not sure if Dockerfile, compose.yaml, or both are allowed)
- sandboxenv[2]: the task run directory as a string

Can you confirm my understanding? 

Would you be open to a PR replacing this tuple with named (and more richly typed) attributes [on a `SandboxEnvironment`](https://github.com/UKGovernmentBEIS/inspect_ai/blob/c1be973c5d27aab69baf600d8c2faac40ef3a489/src/inspect_ai/util/_sandbox/environment.py#L18-L18)? That would make this area of the codebase easier to understand and maintain (e.g. [this](https://github.com/UKGovernmentBEIS/inspect_ai/blob/c1be973c5d27aab69baf600d8c2faac40ef3a489/src/inspect_ai/_eval/run.py#L308-L349) is quite hard to follow). But perhaps there's some specific reason this was not made a part of `SandboxEnvironment`?

Yes, I think we can definitely make things better here! 

The reason there is a separate `SandboxEnvironmentSpec` class is for instantiation from plain text (e.g. on the CLI `--sandbox docker,compose.yaml`). So we need to keep that, but I think we could definitely make it a named tuple. In order to keep all of the existing code running we would need the places where users pass in a `sandbox` (`Task`, `eval()`, `eval_set()`, etc.) to all also take a raw tuple that we'd convert into a named tuple.

I think that `resolve_sandbox_for_task()` could also return a named tuple.

In terms of things being directly on the `SandboxEnvironment`, I'd be generally in favor of that but note we need to preserve binding using simple specifications / config file syntax. That said, I think we could sort out getting anything useful that would make the code more clear onto the `SandboxEnvironment` instance.

Thanks for offering to make a PR --- would be happy to review/merge this but note I am also very happy to take this on as I think you've identified a major soft spot and I'm also quite motivated to fix it. I'd probably work on this over the next week or so. LMK either way and we will get this sorted out soon.


Thanks for the detailed reply!

Since you're motivated to fix this in the short term, I think you taking this one on is the better allocation of work.

> That said, I think we could sort out getting anything useful that would make the code more clear onto the SandboxEnvironment instance.

To be clear, I'm not strongly advocating for that specific design. I'm happy for you to make the granular-level decisions here :).

My main desire is that internal functions should pass around an object that:
- is an instance of a named type
- has named fields
- has fields with (rich) type information (e.g. not just plain `str`)

My overall goal is for this area of the codebase to be easier to understand and refactor. For context, what prompted this issue for me is that I spent the whole day Friday thinking I could put up a PR to fix https://github.com/UKGovernmentBEIS/inspect_ai/issues/691, but I had to give up in the end :).

---

Here are some of my more opinionated takes (these are less important and may be wrong):
- I think anything to do with parsing CLI input should be handled inside `_cli`, and should not affect the types in the main application. You already use `click` which has a bunch of nice features for that.
- For paths, I favour using `pathlib.Path` instead of `str`. It avoids ambiguity between relative and absolute paths and is portable across OSes.

Do you mind letting me know when you've got a PR up, but before merging it, so I can potentially chime in?

Yes, will do! 

PR for this is up here: https://github.com/UKGovernmentBEIS/inspect_ai/pull/703

Resolved with: https://github.com/UKGovernmentBEIS/inspect_ai/pull/703