Parallax signal contract and verification
Defines the current run, trace, span, log, and metric contract with priorities, verification criteria, and open questions.
Summary
The target contract uses stable run identity, linked workflow traces, typed spans and errors, clean structured logs, low-cardinality metrics, and verification against Parallax behavior.
Question and scope
What signal model should jackin❯ expose, which structural changes must precede noise reduction, and how should the resulting contract be verified?
Method
This synthesis uses the dossier findings, tracing analysis, UI evidence, and raw-data analysis.
Findings
Runs
Run is the top-level correlation unit:
parallax.run.idservice.name=jackinservice.versionjackin.component=host|capsulejackin.workspacejackin.workspace.kindjackin.invocation.commandjackin.exit_code
Every log, span, metric, and issue event must carry parallax.run.id.
Traces and linked subtraces
Use one trace per operator-meaningful workflow:
launchcapsule.session.startcapsule.attachusage.refreshimage.buildauth.prewarmagent.session
Use linked subtraces when one workflow contains a large independent subsystem:
- Host launch trace links to BuildKit/buildx trace.
- Host launch trace links to capsule session trace via propagated
traceparent. - Capsule session trace links to child agent session traces.
- Usage refresh trace links to provider probes when provider work is concurrent or high-volume.
Do not force all sub-activity into one giant trace. Use span links and shared parallax.run.id / session.id / jackin.workflow.id.
Spans
Spans should be user/workflow operations, not every loop iteration:
- Good:
launch.build_derived_image,docker.container.inspect,capsule.attach,usage.refresh_accounts. - Bad as default spans:
emit_insn,read_page_no_cache,bind_and_rewrite_expr, terminal byte send/parse loops.
Rules:
- Use spans for things with duration and causal hierarchy.
- Use span events for notable details inside a span.
- Use metrics for counters/gauges/hot-loop counts.
- Use logs for human diagnostic facts.
Logs
Log body should be short and readable:
capsule attach failedAttributes should carry structure:
severity=ERROR
event.name=capsule.attach.failed
jackin.component=host
jackin.operation=capsule.attach
jackin.stage=attach
error.type=attach_error
container.name=jk-qfrehkbv-holla-thearchitect
command.name=docker
command.args_redacted=["exec","-e=JACKIN_HOST_ALT_SCREEN=1","<container>","/jackin/runtime/jackin-capsule"]
parallax.run.id=18bc74b282b0a850
trace_id=...
span_id=...Console renderer may display:
[jackin debug docker] inspect container jk-... -> runningBut backend export should be:
body="inspect container"
log.category="docker"
docker.object="container"
docker.action="inspect"
container.name="jk-..."
container.state="running"
diagnostic.tier="debug"Metrics
Move high-frequency observations into metrics:
jackin.terminal.bytes_sentjackin.terminal.cursor_movesjackin.render.duration_usjackin.render.painted_cellsjackin.usage.accounts_refreshedjackin.db.statement_countjackin.db.read_pagesjackin.docker.inspect_countjackin.errors.countbyerror.type
Metrics should be grouped by low-cardinality labels only.
Implications for jackin❯
Rust implementation guidance
- Use
tracingspans for work units and events for point facts, matching the crate model. - Use
EnvFilterper layer so console, local file, OTLP logs, and OTLP spans can have different filters. - Keep target/module filters for dependency noise, but do not disable jackin❯ operation spans needed for development.
- Prefer explicit fields over formatted strings:
tracing::info!(
target: "jackin::launch",
event.name = "launch.plan.selected",
jackin.operation = "launch.plan",
jackin.stage = "plan",
event.outcome = "success",
plan = %plan_name,
"launch plan selected"
);Bad default OTLP body:
[jackin debug docker] inspect container jk-abc -> runningGood structured log:
body="container inspected"
severity=DEBUG
event.name=docker.container.inspect
jackin.category=docker
docker.object=container
container.name=jk-abc
container.state=runningParallax UX requirements
- Logs page should show severity filter with OTel severity ranges, not only raw
severity_text. - Logs page should show columns for
event.name,jackin.operation,jackin.stage,event.outcome,error.type. - Run page should default to
INFO+lifecycle timeline and hideDEBUG/TRACEbehind toggles. - Trace page should let operator toggle span events/logs by severity.
- Bundle should include:
INFO+timeline,- warnings/errors,
- top slow spans,
- linked subtraces,
- artifact links,
- optional
DEBUG/TRACEsections only when requested.
Structured logs
- Add a structured diagnostic event API beside current
clog!/cdebug!. - Keep existing console strings for terminal/file output.
- Export OTel logs with structured attributes and clean bodies.
- Add category attributes for debug logs instead of bracket prefixes.
- Redact sensitive values before any OTel export.
- Cap or artifact-route large payloads (
docker inspect, capsule log tails, raw command output). - Add tests asserting:
- console line still has old prefix where needed,
- OTel/log event body has no prefix,
log.categoryexists,- secrets are redacted,
- huge payloads are summarized.
Coverage prerequisites
Before removing or downsampling noisy rows, add typed coverage to the operations that currently depend on those rows for diagnosis:
- Wrap
ShellRunnerwith spans/logs for every subprocess:process.commandprocess.args_redactedprocess.cwd.kindprocess.exit_codeprocess.duration_mserror.typeon failure.
- Wrap HTTP metadata and download helpers:
- host and route class, not full secret-bearing URL where unsafe,
- status code,
- bytes,
- retry count,
- timeout/cancel/error type.
- Wrap Docker lifecycle operations:
- object type/name,
- action,
- state before/after,
- exit code,
- duration.
- Convert nested
timing_started/doneevents into real child spans or span events where the duration matters in the waterfall. - Promote launch stage details into attributes and stable span names.
- Add coverage tests using a fake runner/export sink so a regression cannot silently remove spans/log attrs for critical operations.
Error semantics
- Add domain error helpers:
record_error(error_type, message, attrs)record_exception(error, attrs)
- Mark active span status
ERRORwhen a workflow fails. - Emit OTel
ERRORlogs for actual failures, notINFOdiagnostic rows. - Normalize issue fingerprints:
- include stable error type/operation/component,
- exclude container ids, run ids, temp paths, branch names, uid/gid, raw command strings.
- Replace
log_error: ...titles with domain titles.
Trace shape
- Rename launch spans or set
otel.nameso waterfall rows are meaningful. - Make logs inherit the active trace/span context.
- Split huge workflows into linked subtraces:
- launch trace,
- build trace,
- attach trace,
- capsule session trace.
- Emit standard OTel span links for subtraces, and let Parallax store/render derived
parallax.parent_trace_idnavigation fields. - Drop dependency-internal spans from default export only after equivalent workflow-level spans/metrics exist.
- Convert hot-loop and storage-engine details into metrics/span events.
Parallax UX contract
Even though this is mainly a jackin❯ telemetry problem, define the backend-facing contract:
- Logs page can filter by
parallax.run.id,jackin.component,log.category,jackin.operation,error.type,stage. - Issues page groups by stable fingerprint.
- Trace page displays operation + stage.
- Run page shows:
- top failures,
- linked traces,
- correlated logs,
- metrics around run,
- redacted evidence bundle.
- Trace page shows linked subtraces and backlinks using OTel span links plus Parallax-derived relation fields.
Verification criteria
Run a new jackin --debug under Parallax and verify:
DEBUGvolume is at least an order of magnitude lower, unless an explicit internal-firehose flag is enabled.- No OTel log body contains
[jackin debug. - No OTel log body contains raw API-token-shaped values.
parallax issue listgroups repeated capsule attach failures into one issue.- A forced attach failure creates:
- one
ERRORlog, - one error span or failed parent workflow span,
- stable
error.type, - stable issue fingerprint,
- link to run and trace.
- one
- Launch trace waterfall rows are visually distinct.
- Run detail trace has correlated logs (
Logs > 0) for stages that emitted logs. emit_insnand storage-engine spans disappear from default trace lists.
Limitations and unknowns
- Should raw local diagnostics files preserve full debug payloads when OTLP export is active, or only when
JACKIN_DIAGNOSTICS_FILE=1is set? - What is the exact allowlist for OTel-exported attributes versus local-only artifacts?
- Should Parallax issue fingerprinting be fixed in Parallax, jackin❯, or both? jackin❯ should still send stable fields so any backend can group correctly.
- What threshold should promote debug events into span events versus metrics?
- Which workflows need linked subtraces first: launch/build/attach likely first, usage refresh second.