Commit 9caffcb
feat(harbor): task.yaml/experiment.yaml → Harbor export + coder-eval as a Harbor agent (#166)
* feat(harbor): export coder-eval tasks to Harbor, with coder-eval as the grader
Implements C0/C1.1/C1.4/C2/C3(golden) of the Harbor interop plan
(tmp/harborframework.md): `coder-eval export --format harbor <task.yaml> -o
<dir>` emits a Harbor task directory whose `tests/test.sh` grades with
coder-eval's own criteria via a two-line verifier shim.
- `coder_eval.harbor.reward` — translates a graded run's task.json into
Harbor's reward.json contract. A missing/unmeasured weighted_score writes
no reward file (never coalesced to 0.0), so Harbor's own
RewardFileNotFoundError path masks the trial instead of scoring it zero.
- `coder_eval.harbor.portability` — classifies all 15 criterion types so an
unsupported criterion is refused at export time, not as a mystery low
reward at verify time. Registry-derived coverage over the real
SuccessCriterion union.
- `coder_eval.harbor.packager` — the export writer itself: task.toml,
instruction.md, environment/, tests/test.sh, tests/task.yaml,
tests/reference/. New dependency: tomli-w.
- `coder-eval harbor reward` / `coder-eval export` CLI commands.
- CE004 widened to scope harbor/ as a core layer (must not import
coder_eval.cli).
Verified live against real Harbor 0.22.0 + real docker (not just unit
tested): exported tasks scored reward 1.0 (correct solution), 0.5 (wrong
content, genuinely measured not masked), and correctly masked with no
solution present. Two bugs the live run found and fixed that no unit test
caught: test.sh referenced tests/task.yaml as cwd-relative when Harbor
uploads the whole tests/ tree to the absolute /tests/; and `set -e` in
test.sh was silently discarding every real failing score as if it were
unmeasured, since `coder-eval evaluate` exits non-zero on a failed
criterion (a measured verdict, not an infra failure).
v1 assumes the exported task's Dockerfile is FROM coder-eval-agent:<tag>
(confirmed live) so the verifier's `coder-eval` binary is present; the
packager warns, non-blocking, when it can't confirm that.
Full design, verification log and known follow-up (C1.2/C1.3, solution/
auto-derivation, network:none, docs) recorded in tmp/harborframework.md.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(harbor): derive a prebuilt image's real WORKDIR instead of guessing /app
Converting a real in-tree task (hello_date_smoke_test) through the export
pipeline surfaced a live bug in the bare-`docker.image` branch of
`_write_environment`: it defaulted `workdir` to the hardcoded
`DEFAULT_WORKDIR = "/app"` whenever `sandbox.docker.working_dir` was unset,
regardless of the image's actual WORKDIR.
`coder-eval-agent:latest`'s real WORKDIR is `/work`. Harbor's shared verifier
runs `docker exec -w <workdir> <container> ...`, and confirmed live that
`docker exec -w` -- unlike `docker run -w`, which auto-creates the directory
-- hard-fails to chdir into a path that doesn't already exist in the image
("no such file or directory"), surfacing as agent exit 127 with no verifier
output at all. The dockerfile_path branch never had this bug (it appends a
WORKDIR line and the directory exists once Docker builds it); the bare-image
branch had no Dockerfile to fix and no way to introspect the image, so it
just guessed.
Fix: `_inspect_image_workdir()` runs `docker image inspect <image> --format
'{{.Config.WorkingDir}}'` (best-effort, 30s timeout, returns None on any
failure) and the bare-image branch now tries, in order: explicit
`working_dir` -> inspected WORKDIR -> `DEFAULT_WORKDIR`, warning
(non-blocking) only on the last fallback.
Re-verified live after the fix: `harbor run -p <dir> -a oracle` against the
converted hello_date task scored reward: 1.0.
Test hygiene: added an autouse fixture stubbing `_inspect_image_workdir`
across `test_harbor_packager.py` so packager unit tests never depend on
what happens to be cached in the local docker daemon -- a real image named
`byod-custom-image:0.1.0` (this file's own placeholder name), built by an
unrelated docker-integration test elsewhere in the suite, silently flipped
a DEFAULT_WORKDIR assertion the first time this ran locally. New tests
(TestPrebuiltImageWorkdirInspection) cover the inspection helper directly
and its three-way fallback order.
Full narrative in tmp/harborframework.md (gitignored), including a scoping
note for the next piece (coder-eval as Harbor's *agent*, not just its
verifier) -- not started, planning only.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* feat(harbor): export experiment.yaml variants to Harbor task directories
Extends the single-task Harbor exporter to experiment.yaml: each resolved
(task, variant, replicate[, dataset row]) combination gets its own Harbor
directory, since Harbor's task.toml has no variant concept. Reuses
resolve_all_tasks (the same pipeline `run -e` uses) for resolution, and
skips (rather than silently drops) a variant whose agent/simulation
override Harbor's verifier-only export cannot honor, detected precisely
via config_lineage so a task's own agent config never false-triggers it.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* feat(harbor): coder-eval as a Harbor agent (C1.2)
Adopts ATIF (Agent Trajectory Interchange Format) as coder-eval's
trajectory interchange layer so a Harbor trial can run coder-eval itself
as the agent, not just as the grader.
- harbor/atif_models.py + atif_emit.py: vendored ATIF schema + a pure
EvaluationResult -> Trajectory converter, opt-in via `--format harbor`
on `execute`/`run` (writes a trajectory.json sibling to task.json;
never changes default output).
- harbor/atif_hydrate.py: the reverse direction (Trajectory -> TurnRecords)
so `evaluate --format harbor --trajectory <path>` can grade
trajectory-dependent criteria against an ATIF file that didn't
originate from an in-process run.
- harbor/agent.py: CoderEvalAgent(BaseInstalledAgent) — a real Harbor
agent that shells out to `coder-eval execute --format harbor` inside
the container and lets Harbor discover the resulting trajectory.json
via `populate_context_post_run`, matching Harbor's own ClaudeCode
agent's exact convention. Verified end-to-end against a real
harbor==0.22.0 install: a full export -> docker build -> `harbor run`
-> grade round trip produces correct rewards for both a passing and a
deliberately failing criterion.
- packager.py: bakes a criteria-free agent-phase task.yaml into the
image at a fixed path (agent_paths.py) via a Dockerfile COPY line, so
CoderEvalAgent always has a task to execute without ever seeing the
real success_criteria.
- run_command.py: when `--format harbor` writes exactly one trajectory
(the shape a CoderEvalAgent invocation always produces), it is also
copied to <run_dir>/trajectory.json so a fixed-path caller (Harbor's
agent log dir) can find it without knowing coder-eval's internal
variant/task/replicate nesting.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* feat(harbor): fix agent workspace alignment, env passthrough, and template sources
Several fixes to the Harbor export/agent pipeline, each verified against a
real `harbor==0.22.0` install with real Docker and (where relevant) real
Bedrock credentials:
- CoderEvalAgent now passes --workspace-dir "$(pwd)" to `coder-eval execute`,
and BatchRunConfig/run_batch/run+execute CLIs gained a matching
--workspace-dir flag (Orchestrator already supported this internally for
DockerRunner). Without it, the agent phase wrote to a throwaway tempdir the
verifier phase never looked at, silently scoring every criterion 0.
- packager.py now emits [environment.env]/[verifier.env] in task.toml, derived
from the resolved task's own sandbox.docker.env_passthrough (the same
allowlist DockerRunner already uses) rather than requiring the operator to
hand-edit task.toml. HOME is excluded (that entry only makes sense paired
with DockerRunner's ~/.claude bind-mount). Values are `${VAR:-}` templates
(empty default) so Harbor doesn't hard-require every var to be present.
- environment/Dockerfile is now always written (synthesized from
sandbox.docker.image when no dockerfile_path is set), so the CoderEvalAgent
embed always has somewhere to COPY task.yaml into.
- instruction.md is now a fixed placeholder pointing at environment/task.yaml
and the CoderEvalAgent agent, instead of leaking the real prompt to a
stock Harbor agent that isn't the one this export is built for.
- environment/task.yaml's success_criteria is now a real `[]` instead of a
placeholder criterion, now that TaskDefinition.validate_success_criteria
(the "at least one criterion" check) has been removed.
- TemplateDirSource directories are now copied into
environment/templates/<n>-<name>/ with their path rewritten to the
in-container copy; environment/task.yaml's sandbox block is field-merged
(driver forced to tempdir) instead of being replaced wholesale, so
python.env_packages/limits/etc. survive.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* ci(harbor): add Harbor E2E workflow (export + CoderEvalAgent round trip)
Installs harbor==0.22.0 alongside coder-eval in the same venv, builds the
coder-eval-agent and byod-custom-image Docker images, then exports and runs
four scenarios via `hb run -a coder_eval.harbor.agent:CoderEvalAgent`:
baseline (plain docker driver, default image), llm_judge (real judge call
inside the verifier phase), docker_custom_image (reuses tasks/byod_smoke_test.yaml's
dockerfile_path + custom image), and template_sources (TemplateDirSource
copy-in). Each scenario asserts reward.json == 1.0, a real ATIF
trajectory.json, and both agent- and verifier-side task.json.
Verified locally end-to-end against real Docker + real Bedrock credentials
before committing (all four scenarios: reward 1.0, no exceptions).
Triggered on workflow_dispatch/schedule/push-to-main only (not pull_request)
so it's informational rather than a required PR check for now — it depends
on live model calls and Docker builds, and Harbor's own release cadence is
independent of this repo's.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(harbor): suppress pyright reportMissingImports for the harbor package
`harbor` is intentionally not a project dependency -- coder_eval.harbor.agent
only ever runs inside a Harbor trial container, where it's already present
(see the module's own ImportError message). CI's Quality Gate installs the
codex/litellm extras, which cleared those pre-existing pyright errors, so
these 3 harbor.* import errors were the only real failures blocking PR #166 --
scoped `# pyright: ignore[reportMissingImports]` on the same 3 lines, matching
the existing pattern for openai_codex's optional import in codex_agent.py.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(tests): harden harbor CLI-error assertions and Windows chmod checks
Two more CI-only failures found running PR #166's full Quality
Gate/Windows Smoke Test jobs (masked previously by the typecheck failure
that aborted before the test step ran):
- test_execute_format_harbor.py / test_evaluate_format_harbor.py assert a
plain substring ("Unsupported --format", "--trajectory") against a raised
Click/Typer error's rendered output. CI renders that error box with color,
which splits "--format"/"--trajectory" across ANSI escape sequences and
silently breaks a naive substring check -- reproduced locally with
FORCE_COLOR=1. Fixed with click.unstyle(result.output) before asserting.
- Two harbor packager tests assert the exported test.sh's chmod executable
bit, which is meaningless on NTFS (Windows Smoke Test runs on Windows).
Skipped/guarded the same way test_sandbox.py already does for other
POSIX-only behavior.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(harbor): address code review findings from full 8-axis review
Fixes surfaced by /coder-eval-code-review-full over two iterations:
- Refuse a task with empty success_criteria under `run`/`evaluate`
(grade=True) -- it previously loaded and would silently score
FinalStatus.SUCCESS at weighted_score 0.0 since
validate_success_criteria was removed to let the criteria-free
Harbor agent-phase task.yaml round-trip through `execute`.
`execute` (grade=False) still accepts it. Scoped to the
post-`--resume` task set so an already-finalized row is never
blocked.
- Refuse a path-traversal-shaped variant_id/task_id/row_id in
experiment export (`_out_subdir`) instead of silently writing
outside `-o`'s output directory.
- Convert `--workspace-dir` misuse (docker driver, >1 task) from an
unhandled ValueError/traceback into a clean typer.BadParameter.
- Escalate a missing `template_sources` directory during export from
a warning to a hard failure -- the agent-phase task.yaml still
references it, so a silently-skipped copy shipped an export with no
starter code.
- Add a `harbor` optional extra (pinned harbor==0.22.0) so
harbor/agent.py type-checks against real types instead of scoped
pyright ignores; wire it into the two CI jobs that run pyright and
simplify harbor-e2e.yml's install step to use it.
- New test coverage: harbor/agent.py's run()/populate_context_post_run
(previously zero coverage), the empty-criteria and workspace_dir
guards, the path-traversal refusal, and the template-source warn vs.
hard-fail branches.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(test): strip ANSI color before asserting --workspace-dir in CLI output
CI renders Click's error box with color, splitting "--workspace-dir"
across escape sequences and breaking the new
test_workspace_dir_with_docker_driver_is_a_clean_cli_error test that
raw-substring-matched it. Same fix as the existing --format/--trajectory
tests: assert against click.unstyle(result.output) instead.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* fix(harbor): address PR review blockers (score-integrity, security, drops)
Closes out the reviewer's Top-5 priority actions from the full 8-axis
review of this branch, plus the two CodeQL findings:
- Restore the empty-`success_criteria` refusal at the layers `run
--to_run`'s guard didn't cover: `regrade_in_place` (shared by `evaluate
<run_dir>` and `run --resume`'s `to_grade` set), the orchestrator-direct
`evaluate` branch, and the resume `to_grade` partition itself. Without
this, a criteria-less task graded SUCCESS at weighted_score 0.0 and
exited 0.
- Widen `write_reward`'s unmeasured-row guard to also refuse
`final_status.category == "error"`, since a grading-time infra crash
(JudgeInfrastructureError/CheckerMisuseError/ReferenceTamperedError)
finalizes ERROR with weighted_score 0.0, not None -- publishing a crash
to Harbor as a measured zero.
- Read `result_status`/`duration_ms` back out of ATIF's ToolCall/
ObservationResult `extra` in atif_hydrate, so `command_executed
(require_success: true)` no longer silently scores 0.0 on the
`evaluate --format harbor` path for a command that succeeded.
- Replace the two hand-picked export payloads: carry `run_limits` (both
agent-phase and verifier task.yaml) and `checker_context` (verifier)
through instead of dropping them, and refuse exporting a `dataset:`-
backed task (unexpanded `${row.*}` placeholders) or an enabled
`simulation:` block.
- `_unhonorable_override_reason` no longer skips agent-override variants:
CoderEvalAgent (C1.2) now carries `task.agent` verbatim and executes it,
so `export -e experiment.yaml` exports one directory per variant instead
of exiting with zero.
- shlex.quote the task-YAML-controlled `working_dir` interpolated into the
generated Harbor verifier `tests/test.sh` (command injection via a
crafted `sandbox.docker.working_dir`).
- Drop symlinks (never dereference) when copying template/reference trees
into an export, matching every other task-authored-tree copy in `src/`;
wrap the reference copy's OSError as TaskNotExportableError.
- `--` before the task-controlled image name in `docker image inspect`.
- Fix the SubagentTrajectoryRef vendored ATIF model to match harbor==0.22.0
exactly (verified against the installed package): all four fields
optional, `session_id` added -- the old required-`trajectory_id` shape
rejected two of harbor's own valid document forms.
- `evaluate --format harbor`'s write-back now checks `target.mode is
RUN_DIR`, not just `prior is not None`: a synthetic prior seeded from
`--trajectory` on the WORK_DIR shape was planting a spurious task.json
into the Harbor-synced work dir.
- Narrow the DIRECT_WRITE stale-artifact warning suppression for
`workspace_dir` to `IN_CONTAINER_ENV` (CE056) instead of the field
itself: `--workspace-dir` is now also a host-reachable CLI flag, where
the named directory persists across runs exactly like DIRECT_WRITE's
own target.
- Remove an unnecessary `del environment` (CodeQL) and fix a test's
dual import style (`import X.Y` + `from X.Y import Z`, CodeQL) for the
same module.
Regenerated the golden export fixture for the `run_limits` addition.
Full suite green (5706 passed), ruff/pyright/lint clean.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
* build(docker): bake the harbor extra into the coder-eval-agent image
Lets the same per-task agent image double as a Harbor agent image
(coder_eval.harbor.agent:CoderEvalAgent, a
harbor.agents.installed.base.BaseInstalledAgent subclass) without a
separate build, matching the harbor extra already wired into both
pyright CI jobs.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>1 parent 87102a3 commit 9caffcb
55 files changed
Lines changed: 6310 additions & 52 deletions
File tree
- .github
- scripts
- workflows
- docker
- src/coder_eval
- cli
- harbor
- models
- orchestration
- tests
- _fixtures/harbor_export_golden
- expected
- environment
- tests
- reference
- source_task
- environment
- reference
- fixtures/atif
- harbor_e2e/fixtures
- lint/rules
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
80 | 80 | | |
81 | 81 | | |
82 | 82 | | |
83 | | - | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
84 | 86 | | |
85 | 87 | | |
86 | 88 | | |
| |||
385 | 387 | | |
386 | 388 | | |
387 | 389 | | |
388 | | - | |
| 390 | + | |
| 391 | + | |
| 392 | + | |
389 | 393 | | |
390 | 394 | | |
391 | 395 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
59 | | - | |
60 | | - | |
61 | | - | |
62 | | - | |
63 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
64 | 68 | | |
65 | | - | |
| 69 | + | |
66 | 70 | | |
67 | 71 | | |
68 | 72 | | |
| |||
90 | 94 | | |
91 | 95 | | |
92 | 96 | | |
93 | | - | |
| 97 | + | |
94 | 98 | | |
95 | 99 | | |
96 | 100 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
33 | 34 | | |
34 | 35 | | |
35 | 36 | | |
| |||
160 | 161 | | |
161 | 162 | | |
162 | 163 | | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
163 | 181 | | |
164 | 182 | | |
165 | 183 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| 11 | + | |
| 12 | + | |
11 | 13 | | |
12 | 14 | | |
13 | 15 | | |
| |||
82 | 84 | | |
83 | 85 | | |
84 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
85 | 90 | | |
86 | 91 | | |
87 | 92 | | |
| |||
0 commit comments