Skip to content

Commit d69157b

Browse files
author
Mengtao Zhang
committed
add a metrics.json
1 parent e1c6b5b commit d69157b

4 files changed

Lines changed: 25 additions & 6 deletions

File tree

‎README.md‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ representative Harbor run on 2026-07-29 took 20 minutes 53 seconds end to end:
121121
`verifier/reward.json`. Submitted artifacts are collected from the
122122
`mcp-server` service, not the agent container.
123123

124-
The verifier writes numeric `reward.json` fields for `primary_score`, `reward`,
125-
`sharpe`, `cagr`, `max_drawdown`, and `pearson_ic`. `primary_score`, `reward`,
126-
and `sharpe` are the same hidden after-cost Sharpe value.
124+
The verifier writes Harbor-compatible numeric reward fields to
125+
`reward.json`: `primary_score`, `reward`, `sharpe`, `cagr`, `max_drawdown`, and
126+
`pearson_ic`. `primary_score`, `reward`, and `sharpe` are the same hidden
127+
after-cost Sharpe value. `metrics.json` is a separate diagnostic artifact
128+
containing the full official scoring payload, including the complete backtest
129+
metrics, causal-audit result, and refit diagnostics.

‎environment/mcp-server/feature_engineering/evaluation/verifier.py‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828

2929
def _write_outputs(
3030
rewards: dict[str, float],
31+
metrics: dict[str, object],
3132
*,
3233
reward_path: str | Path,
3334
metrics_path: str | Path,
@@ -41,7 +42,7 @@ def _write_outputs(
4142
encoding="utf-8",
4243
)
4344
metrics_file.write_text(
44-
json.dumps(rewards, sort_keys=True, allow_nan=False, indent=2) + "\n",
45+
json.dumps(metrics, sort_keys=True, allow_nan=False, indent=2) + "\n",
4546
encoding="utf-8",
4647
)
4748

@@ -77,6 +78,7 @@ async def verify_submission(
7778
}
7879
_write_outputs(
7980
rewards,
81+
{"ok": False, "metrics": rewards},
8082
reward_path=reward_path,
8183
metrics_path=metrics_path,
8284
)
@@ -152,6 +154,7 @@ async def verify_submission(
152154

153155
_write_outputs(
154156
rewards,
157+
scored,
155158
reward_path=reward_path,
156159
metrics_path=metrics_path,
157160
)

‎environment/mcp-server/tests/test_end_to_end_behavior.py‎

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,9 +157,15 @@ async def test_real_training_submission_and_verification_workflow(self) -> None:
157157
self.assertEqual(
158158
json.loads(reward_path.read_text(encoding="utf-8")), rewards
159159
)
160+
metrics = json.loads(metrics_path.read_text(encoding="utf-8"))
161+
self.assertTrue(metrics["ok"])
162+
self.assertEqual(metrics["primary_score"], rewards["primary_score"])
160163
self.assertEqual(
161-
json.loads(metrics_path.read_text(encoding="utf-8")), rewards
164+
metrics["metrics"]["annualized_sharpe"],
165+
rewards["sharpe"],
162166
)
167+
self.assertIn("fit_diagnostics", metrics)
168+
self.assertNotEqual(metrics, rewards)
163169

164170

165171
if __name__ == "__main__":

‎environment/mcp-server/tests/test_verifier_behavior.py‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,7 @@ async def test_missing_submission_writes_negative_reward_outputs(self) -> None:
188188
)
189189
self.assertEqual(
190190
json.loads((self.root / "metrics.json").read_text(encoding="utf-8")),
191-
expected,
191+
{"ok": False, "metrics": expected},
192192
)
193193
score.assert_not_awaited()
194194

@@ -336,6 +336,13 @@ async def score_hidden(**kwargs: object) -> BacktestResult:
336336
self.assertEqual(calls["hidden_artifact"], replacement_bytes)
337337
self.assertIs(calls["hidden_public_data"], calls["refit_public_data"])
338338
self.assertEqual(rewards["primary_score"], 1.25)
339+
metrics = json.loads(
340+
(self.root / "metrics.json").read_text(encoding="utf-8")
341+
)
342+
self.assertTrue(metrics["ok"])
343+
self.assertEqual(metrics["primary_score"], 1.25)
344+
self.assertEqual(metrics["metrics"]["annualized_sharpe"], 1.25)
345+
self.assertEqual(metrics["causal_audit"], {"visibility": "hidden_fixed"})
339346

340347
async def test_hidden_prediction_attachment_contains_no_outcome_columns(
341348
self,

0 commit comments

Comments
 (0)