Skip to content

Link units

Link a folder of .10x.json symbol units from a prior compile into a single .10x.tar library, with no source scan.

It is the same Cloud-flavor Compiler app invoked with link-only arguments: the units folder is also the output folder and no source is mounted, so the engine reuses the units already on disk and merges them into the library.

Use it to:

  • re-link after editing or pruning units
  • assemble a library from a units tree built piecemeal
  • rebuild a library from the output folder of a prior log10x_compile

Same wait shape as compile: the link waits inline up to max_wait_ms (default 45s). Linking is usually fast, so it normally returns the finished library in one call.

A very large units tree returns a running job_id to poll with log10x_compile_status, and max_wait_ms: 0 returns the job_id immediately.

Example

You

I pruned the units folder. Re-link it into a library.

Log10x

Linked 412 units into symbols.10x.tar (3.4 MB) in 6s. No source scan, no new files traversed. Symbols by type: class 1,180, log 642, exec 410, enum 96.

More to ask

  • "link /work/units and call the library payments"
  • "rebuild the library from my last compile's output folder"
  • "the units tree is huge, kick off the link and give me a job_id"

Prerequisites

The Cloud flavor, docker-first: auto and docker pull log10x/compiler-10x, and local runs a cloud-flavor tenx. The Edge flavor is refused.

This is the CLI tier, so it needs no Kubernetes, deployed app, or Log10x account.

units_path must hold at least one .10x.json unit from a prior log10x_compile. An empty folder is refused with nothing to link.

Schema and samples

Input example

Re-link a pruned units folder into a named library.

{
  "units_path": "/work/symbols-out",
  "library_name": "payments"
}
Input schema

Agent-facing JSON Schema (the canonical shape the MCP server publishes via tools/list):

{
  "type": "object",
  "properties": {
    "units_path": {
      "type": "string",
      "description": "Absolute path to a folder of .10x.json symbol units (produced by a prior compile) to link into a single .10x.tar library. Traversed recursively; the existing units are merged with NO source re-scan, and the .10x.tar is written into this same folder."
    },
    "library_name": {
      "type": "string",
      "default": "symbols",
      "description": "Base name for the linked .10x.tar and the runtimeName. Sanitized to [A-Za-z0-9_.-]."
    },
    "mode": {
      "type": "string",
      "enum": ["auto", "docker", "local"],
      "default": "auto",
      "description": "Execution backend, same contract as log10x_compile: `auto` prefers the cloud compiler image, `docker` forces it, `local` uses a cloud-flavor tenx. The Edge flavor is refused."
    },
    "timeout_ms": {
      "type": "integer",
      "minimum": 10000,
      "maximum": 3600000,
      "default": 600000,
      "description": "Hard cap on link wall time in ms. Default 600,000 (10 min). Linking is much faster than scanning, but a very large units tree can still take minutes."
    },
    "max_wait_ms": {
      "type": "integer",
      "minimum": 0,
      "maximum": 300000,
      "default": 45000,
      "description": "How long to wait inline (ms) for the link to finish before handing back a job_id to poll. Default 45,000 (45s). Linking usually finishes inside this and returns the library in ONE call. A very large units tree returns a running job_id you poll with log10x_compile_status. 0 = fire-and-forget."
    }
  },
  "required": ["units_path"],
  "additionalProperties": false
}

Source: src/tools/compile-link.ts.

Output example

Representative envelope for a fast link that finished inside max_wait_ms. The bounded-sync path returns the log10x_compile_status readout the moment the link completes, so the shape matches that tool: data.payload.job_status is completed, with the produced units, the linked library, and the link diagnostics. The diagnostics.scan_health block is null on a link (no source scan), and link_report populates once the compiler-10x image carries the engine diagnostics change.

{
  "schema_version": "1.0",
  "schema_epoch": "2026-05-25",
  "tool": "log10x_compile_status",
  "generated_at": "2026-06-15T09:12:04.118Z",
  "view": "summary",
  "status": "success",
  "summary": {
    "headline": "Link job `7b2e9c41-...` done: 412 units → /work/symbols-out/payments.10x.tar (3.4 MB)."
  },
  "data": {
    "status": "success",
    "decisions": { "threshold_used": null, "threshold_basis": "default" },
    "source_disclosure": {},
    "scope": {
      "window": "payments_compile",
      "window_basis": "explicit",
      "candidates_count": 412,
      "candidates_usable": 1
    },
    "payload": {
      "job_id": "7b2e9c41-3f5a-4d8e-9b21-6c0f1a2d7e44",
      "job_status": "completed",
      "mode": "docker",
      "image": "log10x/compiler-10x",
      "exit_code": 0,
      "elapsed_ms": 6240,
      "timed_out": false,
      "sources": "link /work/symbols-out",
      "output": {
        "folder": "/work/symbols-out",
        "unit_count": 412,
        "empty_unit_count": 0,
        "library_files": [
          { "path": "/work/symbols-out/payments.10x.tar", "bytes": 3565158 }
        ]
      },
      "diagnostics": {
        "results_available": true,
        "phases": [
          {
            "operation": "link",
            "status": "ok",
            "traversed_files": 412,
            "scanned_files": 0,
            "output_files": 1,
            "warns": 0,
            "errors": 0
          }
        ],
        "scan_health": null,
        "link_report": {
          "merged_files": 412,
          "skipped_files": 0,
          "excluded_by_folder": 0,
          "excluded_by_file_name": 0,
          "merged_repos_count": 1,
          "non_merged_repos_count": 0,
          "symbols_by_type": { "class": 1180, "log": 642, "exec": 410, "enum": 96 },
          "symbols_excluded_by_type": 0
        }
      },
      "log_tail": []
    },
    "human_summary": "Link job 7b2e9c41-... completed via docker in 6s: 412 symbol units, linked to /work/symbols-out/payments.10x.tar (3.4 MB). No files failed to scan. Linked 412 unit files; symbols by type: class 1180, log 642, exec 410, enum 96."
  },
  "actions": [
    {
      "tool": "log10x_validate",
      "args": { "extra_args": [["symbolPaths", "/work/symbols-out"]] },
      "reason": "smoke-test the compiled library against a few sample event lines (supply input_lines)"
    }
  ],
  "truncated": false,
  "warnings": []
}

A units tree too large to link inside max_wait_ms, or a call with max_wait_ms: 0, returns the handoff envelope instead, with data.payload.job_status: "running" and a log10x_compile_status action carrying the job_id.

Output schema

The data block inside the chassis envelope. On the bounded-sync completion path the payload is the log10x_compile_status shape:

interface CompileLinkPayload {
  job_id: string;
  job_status: 'running' | 'completed' | 'failed' | 'timed_out';
  mode: 'docker' | 'local';
  image: string | null;
  exit_code: number | null;
  elapsed_ms: number;
  timed_out: boolean;
  sources: string;
  output: {
    folder: string;
    unit_count: number;
    empty_unit_count: number;
    library_files: Array<{ path: string; bytes: number }>;
  };
  diagnostics: {
    results_available: boolean;
    phases: Array<{
      operation: string | null;
      status: string | null;
      traversed_files: number | null;
      scanned_files: number | null;
      output_files: number | null;
      warns: number | null;
      errors: number | null;
    }>;
    // null on a link (no source scan).
    scan_health: {
      files_failed: number;
      failed_by_language: Record<string, number>;
      failure_samples: Array<{ name: string; language: string; reason: string }>;
    } | null;
    // Populated once the compiler-10x image carries the engine
    // diagnostics change; null otherwise (graceful degradation).
    link_report: {
      merged_files: number;
      skipped_files: number;
      excluded_by_folder: number;
      excluded_by_file_name: number;
      merged_repos_count: number;
      non_merged_repos_count: number;
      symbols_by_type: Record<string, number>;
      symbols_excluded_by_type: number;
    } | null;
  };
  log_tail: string[];
}

When the link overruns max_wait_ms, the handoff payload is smaller: { job_id, job_status: 'running', mode, image, library_file, runtime_name, sources, started_at, timeout_ms, log_file, units_path, unit_count }. Poll log10x_compile_status with job_id for the completed shape above.

Envelope-level fields the agent should also read: status (top-level mirror of data.status), summary.headline (1-line answer), data.human_summary (the quotable plain-English summary), actions[] (next-call chain hints as {tool, args, reason}), truncated, and schema_epoch.