docs: align training privacy maturity
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# Training Case Engine M1-M13 Product README
|
||||
# Training Case Engine M1-M21 Product README
|
||||
|
||||
Training Case Engine is the product-facing training module in AI Exchange. M1-M13 provide persisted training cases, a lightweight HTTP API, a dashboard entry, validation hardening, public package import/export, offline package smoke coverage, and product documentation checks.
|
||||
Training Case Engine is the product-facing training module in AI Exchange. M1-M21 provide persisted training cases, a lightweight HTTP API, a dashboard entry, validation hardening, public package import/export, offline package smoke coverage, product documentation checks, and public response privacy hardening.
|
||||
|
||||
Current product maturity through M13 includes API contract coverage, error contract coverage, the fixture/schema contract, and the offline checks registry smoke.
|
||||
Current product maturity through M21 includes API contract coverage, error contract coverage, the fixture/schema contract, the offline checks registry smoke, recursive public payload sanitization, and public response privacy contract coverage.
|
||||
|
||||
## Dashboard Entry
|
||||
|
||||
@@ -31,7 +31,7 @@ All endpoints use JSON responses. List endpoints accept `limit` with an upper bo
|
||||
| POST | `/training/attempts/{attempt_id}/submit` | Submit an attempt with an optional score. |
|
||||
| GET | `/training/progress` | List progress rows by optional user, skill tag, and limit filters. |
|
||||
|
||||
Public case and package responses omit the internal solution key and private answer details.
|
||||
Public API responses for case list/detail, package export/import, progress, submit, create-attempt, and annotation lifecycle routes are covered by privacy contract tests. Those responses scrub private solution material, including nested internal solution details, before returning JSON.
|
||||
|
||||
## Package Smoke
|
||||
|
||||
@@ -59,12 +59,12 @@ The broader offline check suite also includes this package smoke:
|
||||
- Missing cases return `404` with `not_found`.
|
||||
- Unexpected failures return `500` with `internal_server_error` and do not echo raw internals.
|
||||
|
||||
Package import rejects private internal solution-key fields. Package export is stable public JSON and omits private answer detail.
|
||||
Package import rejects private internal solution fields. Package export is stable public JSON and omits private solution material.
|
||||
|
||||
## Data Isolation Guarantees
|
||||
|
||||
- Training records are scoped to the training domain: cases, tasks, attempts, annotations, scores, and progress.
|
||||
- Training may reference upstream market or rule events as read-only context.
|
||||
- Training APIs and package tooling do not write to signals, executions, backtest results, or live-trading records.
|
||||
- Public package import/export keeps operator-only notes, rubric internals, and private answer detail out of exported payloads.
|
||||
- Public package import/export keeps operator-only notes, rubric internals, and private solution material out of exported payloads.
|
||||
- The offline package smoke uses local files and an in-memory training repository; it writes only the requested public export file.
|
||||
|
||||
@@ -72,7 +72,7 @@ class DocumentationConsistencyTests(unittest.TestCase):
|
||||
|
||||
self.assertEqual(missing, [])
|
||||
|
||||
def test_training_case_product_doc_lists_public_m1_m6_surface(self) -> None:
|
||||
def test_training_case_product_doc_lists_public_m1_m21_surface(self) -> None:
|
||||
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
|
||||
|
||||
for snippet in (
|
||||
@@ -87,25 +87,46 @@ class DocumentationConsistencyTests(unittest.TestCase):
|
||||
"/training/progress",
|
||||
".venv/bin/python scripts/run_training_case_package.py",
|
||||
".venv/bin/python scripts/run_offline_checks.py",
|
||||
"internal solution key",
|
||||
"private solution material",
|
||||
"Data Isolation Guarantees",
|
||||
):
|
||||
with self.subTest(snippet=snippet):
|
||||
self.assertIn(snippet, text)
|
||||
|
||||
def test_training_case_product_doc_reflects_current_m13_maturity(self) -> None:
|
||||
def test_training_case_product_doc_reflects_current_m21_maturity(self) -> None:
|
||||
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
|
||||
|
||||
for snippet in (
|
||||
"M1-M13",
|
||||
"M1-M21",
|
||||
"API contract coverage",
|
||||
"error contract coverage",
|
||||
"fixture/schema contract",
|
||||
"offline checks registry smoke",
|
||||
"public response privacy contract coverage",
|
||||
):
|
||||
with self.subTest(snippet=snippet):
|
||||
self.assertIn(snippet, text)
|
||||
|
||||
def test_training_case_product_doc_names_public_response_privacy_contracts(self) -> None:
|
||||
text = TRAINING_PRODUCT_DOC.read_text(encoding="utf-8")
|
||||
|
||||
for snippet in (
|
||||
"case list/detail",
|
||||
"package export/import",
|
||||
"progress",
|
||||
"submit",
|
||||
"create-attempt",
|
||||
"annotation lifecycle",
|
||||
"privacy contract tests",
|
||||
"scrub private solution material",
|
||||
"internal solution details",
|
||||
):
|
||||
with self.subTest(snippet=snippet):
|
||||
self.assertIn(snippet, text)
|
||||
|
||||
self.assertNotIn("private " + "answer", text.lower())
|
||||
self.assertNotIn("answer " + "detail", text.lower())
|
||||
|
||||
def test_training_case_product_doc_api_routes_match_server_route_request(self) -> None:
|
||||
documented_routes = _training_api_routes_from_product_doc()
|
||||
server_routes = _supported_training_routes_from_route_request()
|
||||
|
||||
@@ -22,6 +22,7 @@ FIXTURE = ROOT / "tests" / "fixtures" / "training_case_package_m6.json"
|
||||
FIXTURE_REF = "tests/fixtures/training_case_package_m6.json"
|
||||
OFFLINE_CHECK_COMMAND = ".venv/bin/python scripts/run_offline_checks.py"
|
||||
PUBLIC_FIELD = "answer" + "_key"
|
||||
PRIVATE_MATERIAL_PHRASES = ("private solution material", "private " + "answer")
|
||||
RESTRICTED_PUBLIC_TEXT = (
|
||||
"data" + "base",
|
||||
"data" + "base_url",
|
||||
@@ -189,7 +190,7 @@ class TrainingCaseDocsCliM10Tests(unittest.TestCase):
|
||||
self.assertEqual(fixture_refs, {FIXTURE_REF})
|
||||
self.assertIn(".venv/bin/python scripts/run_training_case_package.py", text)
|
||||
self.assertIn("public export", lower_text)
|
||||
self.assertIn("private answer", lower_text)
|
||||
self.assertTrue(any(phrase in lower_text for phrase in PRIVATE_MATERIAL_PHRASES))
|
||||
self.assertNotIn(PUBLIC_FIELD, text)
|
||||
|
||||
def test_example_command_uses_supported_cli_flags_and_fixture(self) -> None:
|
||||
@@ -248,7 +249,7 @@ class TrainingCaseDocsCliM10Tests(unittest.TestCase):
|
||||
self.assertIn(FIXTURE_REF, text)
|
||||
self.assertIn("offline package smoke", lower_text)
|
||||
self.assertIn("public export", lower_text)
|
||||
self.assertIn("private answer", lower_text)
|
||||
self.assertTrue(any(phrase in lower_text for phrase in PRIVATE_MATERIAL_PHRASES))
|
||||
self.assertNotIn(PUBLIC_FIELD, text)
|
||||
|
||||
def test_offline_checks_registry_runs_training_package_smoke_entry(self) -> None:
|
||||
|
||||
Reference in New Issue
Block a user