# RAC v0.7.12 — Artifact Lookup and Human-Friendly Resolution

## Status

Planned

## Context

v0.7.11 introduced opaque, system-assigned artifact identifiers.

Representative ID:

```text
RAC-01JY4M8X
```

Opaque IDs provide durable machine identity, but they are not sufficient as the only
human-facing representation.

Users should not need to memorize opaque IDs or manually search repository files to
understand references.

For example, a stored relationship may contain:

```yaml
relationships:
  implements:
    - RAC-01JY4M8X
```

A user needs to understand that the target is:

```text
Markdown Is the Canonical Source Format
Decision · rac/decisions/markdown-first.md
```

This resolution capability must live in RAC Core.

Explorer may provide a richer browsing experience, but it must consume the same lookup
services available to:

- CLI users
- CI pipelines
- Watchkeeper
- IDE integrations
- Scripts
- AI tools

## Requirement

RAC shall provide deterministic artifact lookup, search, and resolution capabilities
for opaque artifact IDs.

Given an ID, RAC shall be able to resolve the canonical artifact and return:

- ID
- Artifact type
- Title
- Path

Where appropriate, RAC may also expose additional existing structural information, but
lookup shall not become a substitute for `inspect` or `portfolio`.

## Goals

- Make opaque identifiers practical for humans.
- Keep ID resolution inside RAC Core.
- Provide stable CLI and JSON contracts.
- Support Explorer without introducing Explorer-only intelligence.
- Allow relationships to be displayed using titles and types.
- Provide actionable errors for unknown and duplicate IDs.
- Preserve a strict boundary between lookup and artifact analysis.

## Initiatives

### Initiative 1 — Core Artifact Resolver

Introduce a repository-level resolver service.

Representative interface:

```python
resolve_artifact(directory, artifact_id) -> ResolvedArtifact
```

Representative result:

```python
@dataclass
class ResolvedArtifact:
    id: str
    type: str
    title: str | None
    path: str
```

The resolver shall use the canonical repository index and identity model.

It shall not independently reimplement:

- File discovery
- Identity extraction
- Artifact classification

The intended dependency direction is:

```text
Repository Index
      |
      v
Artifact Resolver
      |
      +-- CLI
      +-- Explorer
      +-- Watchkeeper
      +-- IDE integrations
```

### Initiative 2 — `rac resolve`

Introduce:

```bash
rac resolve <ID>
```

Example:

```bash
rac resolve RAC-01JY4M8X
```

Human output:

```text
RAC-01JY4M8X

Type: decision
Title: Markdown Is the Canonical Source Format
Path: rac/decisions/markdown-first.md
```

Machine output:

```bash
rac resolve RAC-01JY4M8X --json
```

```json
{
  "schema_version": "1",
  "id": "RAC-01JY4M8X",
  "type": "decision",
  "title": "Markdown Is the Canonical Source Format",
  "path": "rac/decisions/markdown-first.md"
}
```

The directory contract should align with repository intelligence commands.

Representative forms:

```bash
rac resolve RAC-01JY4M8X
rac resolve RAC-01JY4M8X --directory rac/
```

The final argument shape shall be standardized during implementation review.

### Initiative 3 — Artifact Search

Introduce a human-friendly search command.

Representative usage:

```bash
rac find "Markdown canonical"
rac find markdown
rac find --type decision markdown
```

Search may consider:

- ID
- Title
- Filename
- Path
- Artifact type

Search shall not inspect arbitrary prose content in the first version unless explicitly
included in the implementation contract.

Initial search should remain:

- Deterministic
- Explainable
- Fast
- Repository-local

Representative output:

```text
RAC-01JY4M8X  decision  Markdown Is the Canonical Source Format
RAC-01JY4N2Q  design    Markdown Parser Design
```

JSON output shall be available for integrations.

### Initiative 4 — Ambiguity and Failure Handling

Exact ID lookup shall produce one of three outcomes:

1. Exactly one artifact found
2. No artifact found
3. Duplicate ID detected

Unknown ID:

```text
rac: artifact not found: RAC-01JY4M8X
```

Duplicate ID:

```text
rac: duplicate artifact ID: RAC-01JY4M8X

Found in:
- rac/decisions/markdown-first.md
- docs/archive/old-markdown-first.md
```

Duplicate IDs shall never be silently resolved by path order.

Search queries may return multiple matches.

Exact ID resolution shall not.

### Initiative 5 — Relationship Presentation

Update human-facing relationship output to resolve opaque IDs into useful labels.

Stored relationship:

```yaml
relationships:
  implements:
    - RAC-01JY4M8X
```

Human output:

```text
Implements:
- Markdown Is the Canonical Source Format
  Decision · RAC-01JY4M8X
```

JSON output shall retain the canonical ID and may add resolved presentation fields
additively:

```json
{
  "id": "RAC-01JY4M8X",
  "type": "decision",
  "title": "Markdown Is the Canonical Source Format",
  "path": "rac/decisions/markdown-first.md"
}
```

The stored source of truth remains the opaque ID.

Resolved titles and paths are derived repository context.

### Initiative 6 — Explorer Consumption Contract

Expose the resolver through a stable service-layer interface.

Explorer shall use the core resolver to:

- Open artifacts by ID
- Display relationship targets
- Show titles instead of bare IDs
- Navigate after file moves
- Search by title or type

Explorer shall not:

- Maintain a separate ID map
- Implement different fuzzy-matching rules
- Infer identity from filenames
- Resolve duplicates independently

### Initiative 7 — Watchkeeper Consumption Contract

Allow Watchkeeper to present artifact changes using human-friendly labels.

Example:

```text
Relationship added:

Authentication Requirement
RAC-01JY4P7C

now implements:

Markdown Is the Canonical Source Format
RAC-01JY4M8X
```

Watchkeeper shall consume structured resolver output rather than implementing its own
repository scan.

### Initiative 8 — Shell and Automation Usability

Ensure lookup output is useful in scripts.

Potential quiet output:

```bash
rac resolve RAC-01JY4M8X --path
```

```text
rac/decisions/markdown-first.md
```

Or a general field selector:

```bash
rac resolve RAC-01JY4M8X --field path
```

The exact convenience surface is optional for v0.7.11.

The required machine contract is JSON output.

## Implementation Contract

The following decisions are pinned for v0.7.12.

### CLI Shape

```bash
rac resolve <ID> [directory] [--json]
rac find <query> [directory] [--type TYPE] [--json]
```

The directory is positional and defaults to the current directory, mirroring
`rac index`. `--top-level` / `--recursive` follow the standard convention.

### Exit Codes

| Outcome | Exit code |
| --- | --- |
| Artifact resolved | `0` |
| Search completed (matches or none — empty is a valid result) | `0` |
| Artifact not found | `1` |
| Duplicate artifact ID | `1` (repository integrity failure, paths listed on stderr) |
| Invalid usage / not a directory | `2` |

Not-found and duplicate both exit `1` but are distinguishable by message and
by the JSON `error` field.

### Matching Rules

- Exact ID resolution matches the canonical identifier *and* legacy aliases
  (`## ID` value, filename prefix, stem), case-insensitively — the same
  identifier set relationship resolution uses (one identity model).
- Search is a case-insensitive substring match over id, title, filename, and
  path. Result order is deterministic: match-field priority (id, then title,
  then filename/path), then sorted path as the tiebreak.
- Search does not inspect prose content in this release.

### Architecture

- `rac.services.resolve` is built strictly on `build_repository_index` — no
  independent discovery, identity extraction, or classification.
- Relationship human output resolves reference identifiers to
  `Title (Type · ID)` labels through the same index; JSON keeps stored
  identifiers unchanged (ADR-007 — resolved fields may be added additively
  later).
- The `--path`/`--field` convenience selectors are deferred; JSON is the
  machine contract.

## Exit Codes (Roadmap Draft)

Recommended contract:

| Outcome | Exit code |
| --- | --- |
| Artifact resolved | `0` |
| Artifact not found | `1` |
| Invalid command usage | `2` |
| Duplicate identity / repository integrity failure | Existing validation or operational error code |

The final duplicate-ID code should align with RAC's existing exit-code policy.

## JSON Contract

Representative exact lookup:

```json
{
  "schema_version": "1",
  "id": "RAC-01JY4M8X",
  "type": "decision",
  "title": "Markdown Is the Canonical Source Format",
  "path": "rac/decisions/markdown-first.md"
}
```

Representative search:

```json
{
  "schema_version": "1",
  "query": "markdown",
  "match_count": 2,
  "matches": [
    {
      "id": "RAC-01JY4M8X",
      "type": "decision",
      "title": "Markdown Is the Canonical Source Format",
      "path": "rac/decisions/markdown-first.md"
    }
  ]
}
```

Search order shall be deterministic.

The implementation contract shall define ranking and tie-breaking rules.

## Tests

Coverage should include:

- Exact ID resolves one artifact.
- Resolution returns ID, type, title, and path.
- Resolution survives file rename.
- Resolution survives directory move.
- Title changes do not change identity.
- Artifact type changes do not change identity.
- Unknown IDs return the documented failure.
- Duplicate IDs fail explicitly.
- JSON output follows the stable contract.
- Search matches ID.
- Search matches title.
- Search matches filename or path.
- Search type filtering works.
- Search result order is deterministic.
- Explorer-facing services do not depend on Explorer modules.
- Relationship presentation resolves titles without changing stored IDs.
- Empty repositories return valid no-match results.

## Non-Goals

- Full-text semantic search
- AI-assisted artifact discovery
- Embedding indexes
- Remote repository search
- Cross-repository identity resolution
- Ticketing workflows
- Replacing `rac inspect`
- Making Explorer the only lookup interface

## Success Measures

- Users can resolve any opaque ID without manually searching files.
- Relationship output remains understandable to humans.
- Explorer uses RAC Core for all ID resolution.
- Watchkeeper can display titles and types alongside IDs.
- File moves do not break lookup.
- Duplicate IDs are surfaced rather than guessed through.
- CLI and JSON consumers receive the same canonical result.
- Opaque identity does not materially reduce repository usability.

## Related Decisions

- ADR-025 Hybrid Artifact Metadata
- ADR-026 Opaque System-Assigned Artifact Identity
- ADR-015 Explorer as a Consumer

## Dependencies

- v0.7.5 Repository Index
- v0.7.11 Hybrid Metadata and System-Assigned Identity
- Canonical repository discovery
- Core identity validation

## Follow-On Work

Later releases may add:

- Shell completion for artifact IDs
- IDE autocomplete
- Explorer fuzzy navigation
- Cross-repository namespaces
- Alias support
- Full-text or semantic search

These capabilities shall build on the resolver rather than replacing it.