Skip to main content
The Ekanos CLI enforces seat-based verification so you cannot publish to the wrong Ekanos source by accident. A logged-in developer often holds seats on more than one source, and a typo or stale config must never silently publish to the wrong one.

The safety mechanism

Three commands work together:
ekanos sources answers “which sources do I hold a seat on?” From there, ekanos use pins a target and ekanos publish verifies it before uploading anything.

Sources and seats

ekanos sources lists every source on which you hold a developer or source_admin seat:
The * marks the source saved in this project’s ekanos.json. If that slug is not in your list, the output says so. In JSON mode, data is { host, sources: [{ id, slug, name, roles }], activeSource }.

Publish target resolution

ekanos publish resolves its target from:
  1. --source flag (explicit)
  2. source field in ekanos.json (implicit)
With neither, it fails with validation (exit 3): No Ekanos source given for the submission. The hint lists your seats when they can be fetched.

Safety rules

Before packing or submitting anything, publish fetches your seat list and applies these rules:

Plain English

  • One seat? Just publish. Nothing to disambiguate.
  • Explicit --source? Just publish. You said which one.
  • Several seats, source from ekanos.json, human at a terminal? The CLI prints the target and asks Proceed? [y/N].
  • Several seats, source from ekanos.json, script/agent/pipe? Pass --source, or --yes to confirm the target already in ekanos.json.
  • Not a seat you hold? Always forbidden, with a hint listing your actual seats.

Workflow examples

One source

After the first publish, ekanos.json remembers the source:

Several sources

Use ekanos use to switch targets:

Agent publishing

Never pass --yes through an ambiguity you haven’t resolved:

CI/CD pipeline

Commit ekanos.json with the intended source, then either pass --source explicitly or confirm the committed target with --yes:
--yes exists for a human’s already-confirmed intent and for CI pipelines pinned to one source — not as a way to silence the check.

Complete publish flow

  1. Preflight
    • Resolve the host and require a stored session (exit 4 without one)
    • Load ekanos.json and run the schema-skew gate (exit 9)
    • Refuse if the host has declared this CLI version unsupported (exit 9)
    • Resolve the source (exit 3 without one)
  2. Validate
    • Run the same findings pass as ekanos validate
    • Escalate project.host-compiler-rules from warn to error
    • Refuse on any error-severity finding with gate_failed (exit 10) and the findings in data.findings — nothing is uploaded
  3. Verify the target
    • Fetch your seat list and apply the safety rules above
  4. Pack
    • Build a gzipped tarball of ekanos.json, package.json, README.md (if present), root tsconfig*.json and vitest config, and everything under src/
    • Dotfiles, node_modules, and symlinks are excluded
    • Archives over 4 MiB fail with validation (exit 3)
  5. Submit
    • POST to /api/partner/submissions at the package.json version
  6. Report
    • data.source is { id, slug, name } — exactly which source received the submission — alongside submissionId, state, and archiveSha256
    • source (and host, if absent) are saved to ekanos.json

Error handling

Forbidden (exit 5)

Fix: Use a source from the list: ekanos use <source> or ekanos publish --source <source>.

Ambiguous target (exit 3)

Pick one:
  1. Pass --source explicitly this run
  2. Run ekanos use to change the project’s default
  3. Pass --yes only if ekanos.json already names the target you intend

Refused on findings (exit 10)

In human mode, the CLI prints Refusing to publish: 2 findings., then the findings, then ekanos publish failed: 2 errors. In JSON mode, error.message is Refusing to publish: 2 validation findings. and the findings are in data.findings. Nothing was uploaded. Fix: Run ekanos validate, fix the error-severity findings, and publish again.

Version already submitted (exit 7)

The host may return its own message in place of this one; the exit code and hint are the same.

Post-submit monitoring

Use ekanos status to track your submission:
A version moves from submitted (awaiting the gate) to gated (passed the gate, awaiting admission) or rejected, then dev. status --watch polls every 30 seconds and exits 0 on gated or dev, or 10 on rejected with the gate’s findings in data.findings. ekanos status --findings renders each version’s full finding list. See Commands: status for full details.

Troubleshooting

No source configured

publish found no --source and no source in ekanos.json. Either:
  • Run ekanos use <source> to pick one
  • Pass --source <source> to this publish

Source not in your seat list

A typo in the slug, or you don’t hold a seat on it. Run ekanos sources to check the slug; if you need a seat, ask your Ekanos operator.

Republishing the same version

Submitted versions are immutable: republishing the same package.json version exits 7. Bump version in package.json (and in defineIntegration(), which validate checks against it) and publish again.