# AirCoding Artifact Naming and Layout V1

Date: 2026-05-27
Status: Canonical artifact naming/layout standard for V1.0.0 Alpha skeleton

This document defines artifact URI format, directory layout, naming conventions, metadata requirements, compression rules, and evidence linkage.

## 1. Goals

Artifact storage must be:

1. Project-local and session-local.
2. Stable across project moves when using artifact URI and DB records.
3. Queryable through SQLite domain tables.
4. Safe for large logs/binaries/screenshots/pcaps/core dumps.
5. Linked to tool/command/task/agent/evidence records.
6. Compatible with crash recovery and final reports.

## 2. Root Layout

Session artifact root:

```text
<project>/.air/local/sessions/<session-id>/artifacts/
```

Canonical subdirectories:

```text
artifacts/
  messages/
  context/
  command-runs/
  tool-runs/
  builds/
  tests/
  static-analysis/
  debug/
  screenshots/
  pcaps/
  core-dumps/
  diffs/
  reports/
  doctor/
  permissions/
  workspaces/
  ui-assets/
  tmp/
```

`tmp/` is not referenced by `artifacts` table until a file is atomically renamed into a canonical directory.

## 3. Artifact URI

Canonical URI:

```text
artifact://project/<project-id>/session/<session-id>/<artifact-id>
```

Rules:

1. URI is stable and stored in `artifacts.uri`.
2. Filesystem path is stored in `artifacts.path`.
3. Consumers should prefer URI + DB lookup over reconstructing paths.
4. Artifact IDs are opaque stable IDs, not semantic filenames.

## 4. Artifact ID

V1 artifact ID format:

```text
art_<ulid>
```

Examples:

```text
art_01JZ7QX4D4N9Y6QZ3C9QH4SX2A
```

Rules:

1. IDs are generated before writing temp files.
2. IDs must be unique within session DB.
3. IDs are not reused after failed writes.
4. Human-readable meaning belongs in filename and metadata, not ID.

## 5. Filename Format

Canonical filename:

```text
<timestamp>-<artifact-id>-<slug><extension>
```

Timestamp format:

```text
YYYYMMDDTHHMMSSmmmZ
```

Examples:

```text
20260527T142233120Z-art_01JZ7QX4D4N9Y6QZ3C9QH4SX2A-build-log.txt.gz
20260527T142240992Z-art_01JZ7QXXM8WAPVTA5Y4F4P5NTQ-screenshot.png
20260527T142251002Z-art_01JZ7QY8P6PR3G2T5BXE91D6KD-diff.patch
```

Slug rules:

```text
lowercase
ascii letters/numbers/hyphen only
collapse repeated hyphens
max 64 chars
no secrets, usernames, absolute paths, tokens, or raw command strings
```

## 6. Type to Directory Mapping

| Artifact type | Directory | Default extension |
|---|---|---|
| `message_snapshot` | `messages/` | `.json.gz` |
| `context_pack` | `context/` | `.json.gz` |
| `stdout` | `command-runs/<command-run-id>/` | `.stdout.txt.gz` |
| `stderr` | `command-runs/<command-run-id>/` | `.stderr.txt.gz` |
| `combined_output` | `command-runs/<command-run-id>/` | `.combined.txt.gz` |
| `tool_output` | `tool-runs/<tool-run-id>/` | `.json.gz` |
| `build_log` | `builds/` | `.txt.gz` |
| `test_report` | `tests/` | `.json` or `.xml` |
| `static_analysis_report` | `static-analysis/` | `.json` |
| `debug_report` | `debug/` | `.md` |
| `backtrace` | `debug/` | `.txt` |
| `screenshot` | `screenshots/` | `.png` |
| `pcap` | `pcaps/` | `.pcap` |
| `core_dump` | `core-dumps/` | `.core` |
| `diff` | `diffs/` | `.patch` |
| `review_report` | `reports/` | `.md` |
| `doctor_report` | `doctor/` | `.json` |
| `permission_report` | `permissions/` | `.json` |
| `workspace_diff` | `workspaces/<workspace-id>/` | `.patch` |
| `ui_asset` | `ui-assets/` | `.svg` / `.png` / `.json` |

## 7. Command and Tool Run Layout

Command run artifacts:

```text
command-runs/<command-run-id>/
  <timestamp>-<artifact-id>-stdout.txt.gz
  <timestamp>-<artifact-id>-stderr.txt.gz
  <timestamp>-<artifact-id>-combined.txt.gz
  <timestamp>-<artifact-id>-diagnostics.json
```

Tool run artifacts:

```text
tool-runs/<tool-run-id>/
  <timestamp>-<artifact-id>-input.json.gz
  <timestamp>-<artifact-id>-output.json.gz
  <timestamp>-<artifact-id>-report.md
```

Only store tool input as artifact when needed for audit/debug; secrets must be redacted or omitted according to tool policy.

## 8. Write Protocol

Artifact file write protocol:

```text
1. generate artifact_id
2. write to artifacts/tmp/<artifact-id>.tmp
3. fsync/close where supported and appropriate
4. compute sha256 and size
5. atomic rename into canonical directory
6. insert artifacts row and emit artifact.created in same logical operation
7. link evidence_refs if applicable
```

If DB insert fails after rename, recovery scans orphaned files and either registers or quarantines them under `tmp/orphans/`.

## 9. Compression Rules

Default compression:

| Content | Rule |
|---|---|
| text logs over threshold | gzip |
| JSON context/message snapshots | gzip |
| screenshots PNG/JPEG | no double compression |
| pcap | no compression by default |
| core dumps | no compression by default in MVP |
| small markdown reports | no compression |
| patches | no compression unless very large |

Default threshold:

```text
compress text/json artifacts >= 64 KiB
```

## 10. Metadata Requirements

Minimum artifact row:

```ts
interface ArtifactMetadataV1 {
  schema_version: 1
  producer: "tool" | "command" | "agent" | "scheduler" | "main" | "system"
  content_type?: string
  compression?: "gzip" | "none"
  redaction?: "none" | "partial" | "full" | "not_applicable"
  preview_available?: boolean
  original_path?: string
  command_run_id?: string
  tool_run_id?: string
  task_id?: string
  agent_id?: string
  related_event_ids?: string[]
  notes?: string[]
}
```

DB columns store common query fields separately; metadata is for extra detail.

## 11. Evidence Linking

Artifacts are facts only when linked by `evidence_refs`.

Example:

```text
artifact: command combined output
claim: "cpp.build failed with undefined reference in linker stage"
evidence_ref.kind: command_output
evidence_ref.ref: artifact://...
location_json: { "line_start": 120, "line_end": 148 }
```

Rules:

1. A report may cite many evidence refs.
2. A single artifact may support multiple claims.
3. Evidence claims should be concise and testable.
4. Do not treat artifact existence as proof without a claim.

## 12. Redaction and Sensitive Data

Default local artifacts are not automatically redacted because they are project-local debug evidence.

Before export/share/upload:

```text
preview
redact secrets/credentials/private paths where policy requires
record redaction status
require explicit user authorization
```

Doctor bundles may include full diagnostics and are encrypted for the development team when exported through that channel.

## 13. Retention

Session artifacts are retained with the session by default.

Cleanup candidates:

```text
tmp files
orphaned failed writes
duplicate large command stream chunks after combined artifact exists
old developer logs outside project session artifacts
```

No automatic deletion of evidence-bearing artifacts in MVP unless user explicitly runs cleanup and confirms the policy.

## 14. V1.0.0 Alpha Cut Line

V1.0.0 Alpha skeleton must implement:

1. Artifact ID generation.
2. Canonical URI creation.
3. Directory mapping by artifact type.
4. Temp-write then atomic rename.
5. sha256 and size recording.
6. gzip compression for large text/json.
7. `artifacts` table insertion.
8. `artifact.created` event emission.
9. Evidence ref linking.
10. Orphan scan/quarantine on startup.

Post-MVP:

```text
content-addressed deduplication
artifact browser UI
automatic retention policies
export bundle redaction profiles
remote artifact storage adapters
```
