# Rubrics

## Create a rubric

`client.Rubrics.New(ctx, body) (*RubricResponse, error)`

**post** `/v5/rubrics`

Create a rubric, optionally with its initial criteria in the same request.

The rubric is created for the caller's account at version 1. If the optional
`criteria` field is supplied it must contain at least one entry, and each
entry is created as a criterion attached to the new rubric; omit it to create
an empty rubric and add criteria later via the criteria endpoint. The response
returns the created rubric together with the full detail of any criteria
created in this call.

### Parameters

- `body RubricNewParams`

  - `Title param.Field[string]`

    The rubric title

  - `Criteria param.Field[[]RubricCriteriaInput]`

    Initial criteria to create with the rubric

    - `Title string`

      The Criteria text

    - `Annotations map[string, any]`

      Free-form metadata for the Criteria

    - `Weight float64`

      Weight multiplier for scoring

  - `Tags param.Field[[]string]`

    The tags associated with the entity

### Returns

- `type RubricResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Tags []string`

    The tags associated with the entity

  - `Title string`

  - `Version int64`

  - `ArchivedAt Time`

  - `Criteria []RubricResponseCriterionUnion`

    Full criteria on get, summary (title + weight) on list

    - `type RubricCriteriaResponse struct{…}`

      - `ID string`

      - `CreatedAt Time`

      - `RubricID string`

      - `Title string`

      - `Version int64`

      - `Annotations map[string, any]`

      - `Object RubricCriteriaResponseObject`

        - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

      - `Weight float64`

    - `type RubricCriteriaSummaryResponse struct{…}`

      Slim criteria projection for list endpoints (title + weight only).

      - `Title string`

      - `Weight float64`

  - `Object RubricResponseObject`

    - `const RubricResponseObjectRubric RubricResponseObject = "rubric"`

  - `UpdatedAt Time`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  rubricResponse, err := client.Rubrics.New(context.TODO(), sgpdev.RubricNewParams{
    Title: "x",
  })
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", rubricResponse.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "tags": [
    "string"
  ],
  "title": "title",
  "version": 0,
  "archived_at": "2019-12-27T18:11:19.117Z",
  "criteria": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "rubric_id": "rubric_id",
      "title": "title",
      "version": 0,
      "annotations": {
        "foo": "bar"
      },
      "object": "rubric_criteria",
      "weight": 0
    }
  ],
  "object": "rubric",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## List rubrics

`client.Rubrics.List(ctx, query) (*CursorPage[RubricResponse], error)`

**get** `/v5/rubrics`

List the current account's rubrics, paginated.

Only the latest version of each rubric is returned, and archived rubrics are
excluded (this endpoint has no option to include them). The optional `title`
filter matches as a case-insensitive substring, and the optional `tags` filter
narrows results to rubrics carrying the given tags. Each returned rubric
carries only a slim criteria summary (title and weight per criterion) rather
than full criteria; use the get-rubric endpoint to retrieve full criteria
detail.

### Parameters

- `query RubricListParams`

  - `EndingBefore param.Field[string]`

  - `Limit param.Field[int64]`

  - `SortBy param.Field[string]`

  - `SortOrder param.Field[SortOrder]`

  - `StartingAfter param.Field[string]`

  - `Tags param.Field[[]string]`

    Filter by tags

  - `Title param.Field[string]`

    Filter by title (case-insensitive)

### Returns

- `type RubricResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Tags []string`

    The tags associated with the entity

  - `Title string`

  - `Version int64`

  - `ArchivedAt Time`

  - `Criteria []RubricResponseCriterionUnion`

    Full criteria on get, summary (title + weight) on list

    - `type RubricCriteriaResponse struct{…}`

      - `ID string`

      - `CreatedAt Time`

      - `RubricID string`

      - `Title string`

      - `Version int64`

      - `Annotations map[string, any]`

      - `Object RubricCriteriaResponseObject`

        - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

      - `Weight float64`

    - `type RubricCriteriaSummaryResponse struct{…}`

      Slim criteria projection for list endpoints (title + weight only).

      - `Title string`

      - `Weight float64`

  - `Object RubricResponseObject`

    - `const RubricResponseObjectRubric RubricResponseObject = "rubric"`

  - `UpdatedAt Time`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  page, err := client.Rubrics.List(context.TODO(), sgpdev.RubricListParams{

  })
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", page)
}
```

#### Response

```json
{
  "has_more": true,
  "items": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "created_by": {
        "id": "id",
        "type": "user",
        "object": "identity"
      },
      "tags": [
        "string"
      ],
      "title": "title",
      "version": 0,
      "archived_at": "2019-12-27T18:11:19.117Z",
      "criteria": [
        {
          "id": "id",
          "created_at": "2019-12-27T18:11:19.117Z",
          "rubric_id": "rubric_id",
          "title": "title",
          "version": 0,
          "annotations": {
            "foo": "bar"
          },
          "object": "rubric_criteria",
          "weight": 0
        }
      ],
      "object": "rubric",
      "updated_at": "2019-12-27T18:11:19.117Z"
    }
  ],
  "total": 0,
  "limit": 0,
  "object": "list"
}
```

## Get a rubric

`client.Rubrics.Get(ctx, rubricID) (*RubricResponse, error)`

**get** `/v5/rubrics/{rubric_id}`

Retrieve a single rubric with the full detail of its current criteria.

Returns the latest version of the rubric along with all of its current
(latest-version) criteria in full — not the slim title/weight summary returned
by the list endpoint. Archived rubrics remain retrievable through this
endpoint even though they are hidden from the list endpoint.

### Parameters

- `rubricID string`

### Returns

- `type RubricResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Tags []string`

    The tags associated with the entity

  - `Title string`

  - `Version int64`

  - `ArchivedAt Time`

  - `Criteria []RubricResponseCriterionUnion`

    Full criteria on get, summary (title + weight) on list

    - `type RubricCriteriaResponse struct{…}`

      - `ID string`

      - `CreatedAt Time`

      - `RubricID string`

      - `Title string`

      - `Version int64`

      - `Annotations map[string, any]`

      - `Object RubricCriteriaResponseObject`

        - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

      - `Weight float64`

    - `type RubricCriteriaSummaryResponse struct{…}`

      Slim criteria projection for list endpoints (title + weight only).

      - `Title string`

      - `Weight float64`

  - `Object RubricResponseObject`

    - `const RubricResponseObjectRubric RubricResponseObject = "rubric"`

  - `UpdatedAt Time`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  rubricResponse, err := client.Rubrics.Get(context.TODO(), "rubric_id")
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", rubricResponse.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "tags": [
    "string"
  ],
  "title": "title",
  "version": 0,
  "archived_at": "2019-12-27T18:11:19.117Z",
  "criteria": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "rubric_id": "rubric_id",
      "title": "title",
      "version": 0,
      "annotations": {
        "foo": "bar"
      },
      "object": "rubric_criteria",
      "weight": 0
    }
  ],
  "object": "rubric",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## Update or restore a rubric

`client.Rubrics.Update(ctx, rubricID, body) (*RubricResponse, error)`

**patch** `/v5/rubrics/{rubric_id}`

Update a rubric's fields, or restore a previously archived rubric.

The request body is a discriminated union. Send `{"restore": true}` to restore
an archived rubric (clearing its archived state); send any other field set
(such as `title` or `tags`) to update those fields, carrying forward any field
not supplied. Both paths are append-only and produce a new version of the
rubric rather than mutating the existing row. Updating the fields of an
archived rubric is rejected — restore it first. Restoring a rubric that is not
archived is a no-op that returns it unchanged without creating a new version.

### Parameters

- `rubricID string`

- `body RubricUpdateParams`

  - `Rubric param.Field[RubricUpdateParamsRubricUnion]`

    - `type RubricUpdateParamsRubricPartialRubricRequestBase struct{…}`

      - `Tags []string`

        The tags associated with the entity

      - `Title string`

        The rubric title

    - `type RestoreRequestParam struct{…}`

      - `Restore bool`

        Set to true to restore the entity from the database.

        - `const RestoreRequestRestoreTrue RestoreRequestRestore = true`

### Returns

- `type RubricResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Tags []string`

    The tags associated with the entity

  - `Title string`

  - `Version int64`

  - `ArchivedAt Time`

  - `Criteria []RubricResponseCriterionUnion`

    Full criteria on get, summary (title + weight) on list

    - `type RubricCriteriaResponse struct{…}`

      - `ID string`

      - `CreatedAt Time`

      - `RubricID string`

      - `Title string`

      - `Version int64`

      - `Annotations map[string, any]`

      - `Object RubricCriteriaResponseObject`

        - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

      - `Weight float64`

    - `type RubricCriteriaSummaryResponse struct{…}`

      Slim criteria projection for list endpoints (title + weight only).

      - `Title string`

      - `Weight float64`

  - `Object RubricResponseObject`

    - `const RubricResponseObjectRubric RubricResponseObject = "rubric"`

  - `UpdatedAt Time`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  rubricResponse, err := client.Rubrics.Update(
    context.TODO(),
    "rubric_id",
    sgpdev.RubricUpdateParams{
      OfPartialRubricRequestBase: &sgpdev.RubricUpdateParamsRubricPartialRubricRequestBase{

      },
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", rubricResponse.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "created_by": {
    "id": "id",
    "type": "user",
    "object": "identity"
  },
  "tags": [
    "string"
  ],
  "title": "title",
  "version": 0,
  "archived_at": "2019-12-27T18:11:19.117Z",
  "criteria": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "rubric_id": "rubric_id",
      "title": "title",
      "version": 0,
      "annotations": {
        "foo": "bar"
      },
      "object": "rubric_criteria",
      "weight": 0
    }
  ],
  "object": "rubric",
  "updated_at": "2019-12-27T18:11:19.117Z"
}
```

## Archive a rubric

`client.Rubrics.Archive(ctx, rubricID) (*RubricArchiveResponse, error)`

**delete** `/v5/rubrics/{rubric_id}`

Archive a rubric (soft delete).

This is a soft delete, not a permanent one: it records an archived timestamp on
the rubric while retaining the rubric and its version history, so it can later
be brought back via the restore variant of the update endpoint. An archived
rubric is hidden from the list endpoint but stays retrievable by id. The
rubric's criteria are left untouched — archiving does not cascade to or delete
them. Archiving a rubric that is already archived is rejected.

### Parameters

- `rubricID string`

### Returns

- `type RubricArchiveResponse struct{…}`

  - `ID string`

  - `Deleted bool`

  - `Object RubricArchiveResponseObject`

    - `const RubricArchiveResponseObjectRubric RubricArchiveResponseObject = "rubric"`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  response, err := client.Rubrics.Archive(context.TODO(), "rubric_id")
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", response.ID)
}
```

#### Response

```json
{
  "id": "id",
  "deleted": true,
  "object": "rubric"
}
```

## Domain Types

### Restore Request

- `type RestoreRequestParam struct{…}`

  - `Restore bool`

    Set to true to restore the entity from the database.

    - `const RestoreRequestRestoreTrue RestoreRequestRestore = true`

### Rubric Response

- `type RubricResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `CreatedBy Identity`

    The identity that created the entity.

    - `ID string`

    - `Type IdentityType`

      - `const IdentityTypeUser IdentityType = "user"`

      - `const IdentityTypeServiceAccount IdentityType = "service_account"`

    - `Object IdentityObject`

      - `const IdentityObjectIdentity IdentityObject = "identity"`

  - `Tags []string`

    The tags associated with the entity

  - `Title string`

  - `Version int64`

  - `ArchivedAt Time`

  - `Criteria []RubricResponseCriterionUnion`

    Full criteria on get, summary (title + weight) on list

    - `type RubricCriteriaResponse struct{…}`

      - `ID string`

      - `CreatedAt Time`

      - `RubricID string`

      - `Title string`

      - `Version int64`

      - `Annotations map[string, any]`

      - `Object RubricCriteriaResponseObject`

        - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

      - `Weight float64`

    - `type RubricCriteriaSummaryResponse struct{…}`

      Slim criteria projection for list endpoints (title + weight only).

      - `Title string`

      - `Weight float64`

  - `Object RubricResponseObject`

    - `const RubricResponseObjectRubric RubricResponseObject = "rubric"`

  - `UpdatedAt Time`

# Criteria

## Add a criterion to a rubric

`client.Rubrics.Criteria.New(ctx, rubricID, body) (*RubricCriteriaResponse, error)`

**post** `/v5/rubrics/{rubric_id}/criteria`

Add a single criterion to an existing rubric.

Creates a new criterion at version 1 under the given rubric. Criteria are
versioned independently of the rubric they belong to. The request is rejected
if the target rubric is archived.

### Parameters

- `rubricID string`

- `body RubricCriterionNewParams`

  - `RubricCriteriaInput param.Field[RubricCriteriaInput]`

### Returns

- `type RubricCriteriaResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `RubricID string`

  - `Title string`

  - `Version int64`

  - `Annotations map[string, any]`

  - `Object RubricCriteriaResponseObject`

    - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

  - `Weight float64`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  rubricCriteriaResponse, err := client.Rubrics.Criteria.New(
    context.TODO(),
    "rubric_id",
    sgpdev.RubricCriterionNewParams{
      RubricCriteriaInput: sgpdev.RubricCriteriaInputParam{
        Title: "x",
      },
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", rubricCriteriaResponse.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "rubric_id": "rubric_id",
  "title": "title",
  "version": 0,
  "annotations": {
    "foo": "bar"
  },
  "object": "rubric_criteria",
  "weight": 0
}
```

## Update a criterion

`client.Rubrics.Criteria.Update(ctx, rubricCriteriaID, params) (*RubricCriteriaResponse, error)`

**patch** `/v5/rubrics/{rubric_id}/criteria/{rubric_criteria_id}`

Apply a partial update to a criterion, creating a new version.

Updates are append-only: rather than overwriting the criterion in place, each
update inserts a new immutable version with an incremented version number, so
every prior state stays available through the versions endpoint. Fields not
supplied are carried forward from the current version. The request is rejected
if the criterion does not belong to the rubric named in the path.

### Parameters

- `rubricCriteriaID string`

- `params RubricCriterionUpdateParams`

  - `RubricID param.Field[string]`

    Path param

  - `Annotations param.Field[map[string, any]]`

    Body param: Free-form metadata for the Criteria

  - `Title param.Field[string]`

    Body param: The Criteria text

  - `Weight param.Field[float64]`

    Body param: Weight multiplier for scoring

### Returns

- `type RubricCriteriaResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `RubricID string`

  - `Title string`

  - `Version int64`

  - `Annotations map[string, any]`

  - `Object RubricCriteriaResponseObject`

    - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

  - `Weight float64`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  rubricCriteriaResponse, err := client.Rubrics.Criteria.Update(
    context.TODO(),
    "rubric_criteria_id",
    sgpdev.RubricCriterionUpdateParams{
      RubricID: "rubric_id",
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", rubricCriteriaResponse.ID)
}
```

#### Response

```json
{
  "id": "id",
  "created_at": "2019-12-27T18:11:19.117Z",
  "rubric_id": "rubric_id",
  "title": "title",
  "version": 0,
  "annotations": {
    "foo": "bar"
  },
  "object": "rubric_criteria",
  "weight": 0
}
```

## List criterion versions

`client.Rubrics.Criteria.ListVersions(ctx, rubricCriteriaID, params) (*RubricCriterionListVersionsResponse, error)`

**get** `/v5/rubrics/{rubric_id}/criteria/{rubric_criteria_id}/versions`

List the full version history of a single criterion, paginated.

Because criterion updates are append-only, this returns one entry per version,
exposing every prior state of the criterion, ordered by version descending
(newest first) by default. The request is rejected if the criterion does not
belong to the rubric named in the path.

### Parameters

- `rubricCriteriaID string`

- `params RubricCriterionListVersionsParams`

  - `RubricID param.Field[string]`

    Path param

  - `EndingBefore param.Field[string]`

    Query param

  - `Limit param.Field[int64]`

    Query param

  - `SortBy param.Field[string]`

    Query param

  - `SortOrder param.Field[SortOrder]`

    Query param

  - `StartingAfter param.Field[string]`

    Query param

### Returns

- `type RubricCriterionListVersionsResponse struct{…}`

  - `HasMore bool`

    Whether there are more items left to be fetched.

  - `Items []RubricCriteriaResponse`

    - `ID string`

    - `CreatedAt Time`

    - `RubricID string`

    - `Title string`

    - `Version int64`

    - `Annotations map[string, any]`

    - `Object RubricCriteriaResponseObject`

      - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

    - `Weight float64`

  - `Total int64`

    The total of items that match the query. This is greater than or equal to the number of items returned.

  - `Limit int64`

    The maximum number of items to return.

  - `Object RubricCriterionListVersionsResponseObject`

    - `const RubricCriterionListVersionsResponseObjectList RubricCriterionListVersionsResponseObject = "list"`

### Example

```go
package main

import (
  "context"
  "fmt"

  "github.com/scaleapi/sgp-dev-go"
  "github.com/scaleapi/sgp-dev-go/option"
)

func main() {
  client := sgpdev.NewClient(
    option.WithAPIKey("My API Key"),
    option.WithAccountID("My Account ID"),
  )
  response, err := client.Rubrics.Criteria.ListVersions(
    context.TODO(),
    "rubric_criteria_id",
    sgpdev.RubricCriterionListVersionsParams{
      RubricID: "rubric_id",
    },
  )
  if err != nil {
    panic(err.Error())
  }
  fmt.Printf("%+v\n", response.HasMore)
}
```

#### Response

```json
{
  "has_more": true,
  "items": [
    {
      "id": "id",
      "created_at": "2019-12-27T18:11:19.117Z",
      "rubric_id": "rubric_id",
      "title": "title",
      "version": 0,
      "annotations": {
        "foo": "bar"
      },
      "object": "rubric_criteria",
      "weight": 0
    }
  ],
  "total": 0,
  "limit": 0,
  "object": "list"
}
```

## Domain Types

### Rubric Criteria Input

- `type RubricCriteriaInput struct{…}`

  - `Title string`

    The Criteria text

  - `Annotations map[string, any]`

    Free-form metadata for the Criteria

  - `Weight float64`

    Weight multiplier for scoring

### Rubric Criteria Response

- `type RubricCriteriaResponse struct{…}`

  - `ID string`

  - `CreatedAt Time`

  - `RubricID string`

  - `Title string`

  - `Version int64`

  - `Annotations map[string, any]`

  - `Object RubricCriteriaResponseObject`

    - `const RubricCriteriaResponseObjectRubricCriteria RubricCriteriaResponseObject = "rubric_criteria"`

  - `Weight float64`

### Rubric Criteria Summary Response

- `type RubricCriteriaSummaryResponse struct{…}`

  Slim criteria projection for list endpoints (title + weight only).

  - `Title string`

  - `Weight float64`
