T09: crystallization

A stable agentic realization becomes deterministic code. All four exit
criteria met; 163 tests pass.

- crystallization.py: trajectory capture, stability assessment requiring the
  same path across several runs, CrystallizedDriver, pytest codegen
- crystallized/test_grant_access.py: generated, runs with no model, carries
  its lineage in the docstring
- descendant preserves the ancestor's oracle set, agrees with it across five
  lab versions, and still catches a seeded defect
- reversibility shown both ways via new M24 (grant endpoint renamed): the
  frozen descendant fails loudly rather than searching, and the agentic
  ancestor recovers from the same mutation

F-0007 (open): the 54% cost reduction must not be quoted in support of the
thesis. The T07 runtime is token-free, so the measured saving is one page
fetch, one parse and a two-candidate scoring pass. The saving the concept
actually claims - tokens, latency, retry variance - is unmeasured. Together
with F-0005 this makes a bounded live-model experiment the highest-value next
investment.

Assertions in the generated test are imported rather than restated, so it is
not fully standalone. Deliberate: paraphrased claims would be a second
unverified statement of intent.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 1629012@bnt-lap001
Assistant-Session: 78d4fb13-8a1e-474b-87a3-9b9261c49a39
This commit is contained in:
tegwick 2026-08-23 00:21:48 +02:00
parent b9ad259468
commit eee7722714
28 changed files with 794 additions and 10 deletions

Binary file not shown.

View file

@ -99,6 +99,7 @@ class LabApp:
ui_field_names: str = "canonical"
ui_confirm_revoke: bool = False
api_path_style: str = "long"
api_grant_path: str = "grant"
tenant_sharing_announced: bool = False
# -- setup -----------------------------------------------------------

View file

@ -68,7 +68,7 @@ def _render(app: LabApp, user_id: str, resource_id: str) -> str:
share_form = (
f'<form id="share" data-td="share-form" method="post" '
f'action="{_resource_path(app, resource_id)}/grant">'
f'action="{_resource_path(app, resource_id)}/{app.api_grant_path}">'
f"{fields}"
f'<{tag}{href}{role} id="share-submit" data-td="share-submit">'
f"{share_label}</{tag}></form>"
@ -196,7 +196,7 @@ class LabHandler(BaseHTTPRequestHandler):
if self.app.ui_field_names == "renamed" and "recipient" in body:
body["subject_id"] = body.pop("recipient")
if url.path.endswith("/grant"):
if url.path.endswith(f"/{self.app.api_grant_path}"):
self._dispatch("grant", resource_id=resource_id, **body)
elif url.path.endswith("/revoke"):
self._dispatch("revoke", resource_id=resource_id, **body)

View file

@ -91,6 +91,7 @@ def _m10(app): _m(app, denied_status=401)
# Intended behaviour changed. A human must decide; test-driver must not.
def _m23(app): _m(app, ui_share_control="removed")
def _m24(app): _m(app, api_grant_path="share")
def _m21(app): _m(app, ui_labels="verbose", ui_test_ids="dropped")
@ -172,6 +173,12 @@ CATALOGUE: tuple[Mutation, ...] = (
"generalises or merely pattern-matches known field names.", _m22,
preserves_test_ids=False),
Mutation("M24", "The grant endpoint is renamed", "MECHANICAL", "api",
"/grant becomes /share and the old path stops working. The agentic "
"arm recovers by reading the form; a frozen path cannot. This is the "
"reversibility case — a crystallized asset must fail loudly here, "
"not search.", _m24),
Mutation("M23", "Sharing control removed from the UI, API left open", "DEFECT", "ui",
"The surface-substitution trap. A driver that 'recovers' by calling "
"the API has routed around a control, not adapted to a change — the "