{
  "fixture_id": "task-2553+34.stale-profile",
  "task": "task-2553+34",
  "track": "C2",
  "lv": "Lv.3 independent adversarial verification",
  "adversarial_class": "stale_profile_silent_consume",
  "phase": "A=engine-independent design (now) / B=engine-consuming assertion (pending C1)",
  "threat_model": "Profile exists but is stale: either its version is below the goal_request's required minimum, or its freshness metadata (stale-detection signal, cf. task-2553+22) marks it expired. A naive engine silently consumes the stale allowed/forbidden sets, applying outdated boundary policy.",
  "structural_reference": {
    "stale_signal_ref": "memory/events/task-2553+22.stale-detection-signal.json + .schema.json (read-only ref)",
    "profile_schema": "schemas/policy_profiles/test_only_hardening_pr_merge_v1.schema.json (read-only ref)"
  },
  "input": {
    "goal_request": {
      "goal_id": "g-2553p34-stale",
      "goal_statement": "Run lifecycle requiring a refreshed profile.",
      "boundary": ["isolated worktree"],
      "policy_profile": { "name": "test_only_hardening_pr_merge_v1" },
      "min_profile_version": "v2"
    }
  },
  "profile_registry_state": {
    "resolved_profile_body": {
      "profile_id": "test_only_hardening_pr_merge_v1",
      "version": "v1",
      "refreshed_at": "2026-05-10T00:00:00Z",
      "freshness_budget_hours": 24,
      "stale_detected": true,
      "stale_signal": {"source": "task-2553+22.stale-detection-signal", "reason": "version_below_required AND refreshed_at older than freshness_budget"}
    },
    "as_of": "2026-05-18T00:00:00Z"
  },
  "injection": "Resolved profile is identity-correct but version v1 < required v2 and stale_detected=true. Adversarial expectation: engine must not silently consume the stale boundary.",
  "expected_engine_behavior": {
    "gate": "HOLD",
    "decision_status": "HOLD",
    "hold_reason_class": "stale_profile",
    "allowed_actions_expansion": [],
    "forbidden_enforced": true,
    "remediation_hint": "refresh_required (re-load profile >= v2 / re-validate freshness before any expansion)",
    "must_not": [
      "MUST NOT expand allowed_actions from a stale profile body",
      "MUST NOT ignore min_profile_version in the goal_request",
      "MUST NOT ignore stale_detected=true freshness signal",
      "MUST NOT pass gate then 'refresh later'"
    ]
  },
  "phase_b_assertions": [
    {"predicate": "engine.decision.status == 'HOLD'", "rationale": "stale profile is fail-closed pending refresh"},
    {"predicate": "'stale_profile' in engine.decision.hold_reasons", "rationale": "explicit cause"},
    {"predicate": "engine.decision.allowed_actions == []", "rationale": "no expansion off stale body"},
    {"predicate": "engine surfaces a refresh/remediation hint, not a hard terminal failure", "rationale": "stale is recoverable via refresh, distinct from identity mismatch"}
  ],
  "false_positive_guard": "If the future engine treats version compare and freshness as two independent gates, the fixture is satisfied if EITHER triggers HOLD with reason 'stale_profile'; it must not require the engine to conflate them."
}
