New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

tieline

Package Overview
Dependencies
Maintainers
1
Versions
31
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tieline

Living Story/AC contract and semantic graph grounded in code, tests, help content, and organizational evidence.

Source
npmnpm
Version
0.1.26
Version published
Weekly downloads
580
174.88%
Maintainers
1
Weekly downloads
 
Created
Source

Tieline

Tieline

Tieline keeps product intent from getting lost between docs, tickets, code, and AI agents. It turns how a product and business work into a living, versioned semantic contract, so people and agents share the same reviewed definition of what the product should do and where that behavior lives.

Quick setup

From the repository you want to onboard (requires Node.js 20.12 or newer):

cd /path/to/product-repository
npx -y tieline@latest init

Select the coding agents you use. Tieline creates or updates the .tieline workspace and installs the project-scoped tieline skill for those agents. It configures MCP automatically where the selected agent supports repository or CLI registration; otherwise, follow init's printed manual MCP instruction. Restart or reload the selected agent, then start semantic onboarding:

  • Claude Code: run /tieline
  • Codex: run $tieline
  • Other supported agents: ask the agent to use the installed tieline skill

The agent then discovers product context from the repository, proposes the initial semantic contract for review, and guides the remaining setup. See Detailed setup and configuration for database modes, automation, agent-specific behavior, and advanced options.

How Tieline works

The core hierarchy is:

Capability → User Story → Acceptance Criterion → optional Scenario

Acceptance Criteria (ACs) are the primary graph anchor. Code, test, help, and observation relationships should target the most specific known AC; Story-level links remain useful as a coarse fallback.

Vocabulary

TermMeaning
CapabilityA stable product or business area that groups related Stories
User StoryDesired behavior expressed through actor, goal, and benefit
Acceptance CriterionOne observable outcome that defines when a Story is satisfied
ScenarioAn optional Given/When/Then example for an AC
ObservationAppend-only source evidence: a request, bug, or question
Backlog ItemOptional work used to consolidate Observations before or alongside a Story
ArtifactCode, test, or external help content linked to a Story or AC

Authority model

A Story stays the same kind of record as it moves from ideation to delivery. Its lifecycle determines which system may change it:

LifecycleAuthorityWritable from
backlogplanningPostgres planning tools
in_progressrepository.tieline/spec/**/*.yaml in a code change
productionrepository.tieline/spec/**/*.yaml in a code change
retiredrepository.tieline/spec/**/*.yaml in a code change

Materialization preserves the planning Story and AC stable IDs. Once a code change containing those IDs merges, repository sync claims the matching rows and Postgres becomes a searchable projection. Repository-owned definitions cannot be edited through MCP planning tools.

Normal code review and merge are the acceptance boundary. There is no separate semantic decision system or ownership roster, and semantic warnings do not stop deployment in the MVP.

Four planes

  • Contract plane: strict repository YAML for accepted Stories/ACs; planning Stories/ACs in Postgres while they remain backlog.
  • Evidence plane: append-only Observations (request, bug, question), optional Backlog Items, and confirmed/dismissed relationships.
  • Derived plane: focused Story, AC, Scenario, Backlog Item, and sanitized Observation embedding documents; candidate links, coverage, and freshness.
  • Governance plane: repository history, pull-request review, versioned retrieval profiles, sync checkpoints, conflicts, and audit events.

Observations and Backlog Items do not move into the repository. Repository YAML may retain stable motivated_by pointers without copying their source payloads. Help content also remains external/DB-native; contract links use its stable source + external_id pointer.

Contract YAML

version: 1
capability:
  key: RETRIEVAL
  name: Intent-aware retrieval
  description: People and agents retrieve the right business context.
  stories:
    - key: RETRIEVAL-001
      title: Search with an explicit intent
      actor: support specialist
      goal: find the production behavior behind a question
      benefit: answers are grounded in accepted product intent
      lifecycle: production
      aliases: [production behavior search]
      acceptance_criteria:
        - key: RETRIEVAL-001-AC1
          criterion: Tieline must exclude planning records from support results.
          rationale: Support answers should distinguish shipped behavior from ideas.
          scenarios:
            - given: production and backlog Stories match a query
              when: the support profile is selected
              then: only production contract records must be returned
          links:
            - relation: implements
              provenance: authored
              target:
                kind: code
                repository: tieline
                path: src/adapters/postgres/semantic-repository.ts
            - relation: tests
              provenance: authored
              target:
                kind: test
                repository: tieline
                path: scripts/integration-evidence.ts
                framework_hint: custom-script
            - relation: documents
              provenance: authored
              target:
                kind: help
                source: intercom
                external_id: retrieval-profiles

Accepted Stories store title, actor, goal, and benefit separately and render the familiar “As a … I want … so that …” sentence. Each accepted AC states one observable outcome using <subject> must <outcome> [when <condition>]. Scenarios use framework-neutral Given/When/Then text. Test locators may include a framework_hint, but no test framework is required.

Every link states its provenance: authored for a deliberate human-authored claim, inferred for a derived claim, or materialized for a copied projection.

Stable IDs are identity, not embedding prose. Aliases support alternate language, applicability distinguishes legitimately different behavior, and supersedes converges definitions without deleting history.

Detailed setup and configuration

Requirements and installation

  • Node.js 20.12 or newer.
  • Docker with a running daemon when using --database local.
  • A hosted or remote PostgreSQL database with pgvector when using --database existing.
  • Embeddings are optional for retrieval. An OpenAI-compatible provider, Supabase Edge Function, or the optional local runtime adds vector similarity; full-text and identifier search remain available without one.

No install is required. Bootstrap with the current published CLI explicitly:

npx -y tieline@latest init

This does not add Tieline to the application's dependencies or modify its lockfile. After setup, commands can run through npx -y tieline <command>, which is also how the registered MCP configuration launches the server. A global install also works when a bare tieline command is preferred:

npm install --global tieline
tieline --help

Contributors, or users who specifically need the current main branch, can instead install from source:

git clone https://github.com/knoxgraeme/tieline.git
cd tieline
npm ci
npm run build
npm link
tieline --help

npm link makes that checkout's compiled tieline command available on the current machine. Without it, replace tieline in the examples below with node dist/cli.js from the checkout.

Initialize and onboard a repository

Run init from the repository. It auto-detects the product name, repository name, and code scope, defaults the runtime to offline, and asks one question: which coding agents should receive the onboarding skill. Agents the repository already shows evidence of (.claude/, .agents/, .cursor/, and similar), or the agent whose session is running init, arrive preselected; nothing else does. Selecting the agents is the confirmation: init applies the setup immediately without repeating detected defaults in a second review screen. Everything else — product description, context sources, database upgrades — is gathered conversationally by the agent during semantic onboarding, where it can read the repository first and verify instead of interrogate:

cd /path/to/product-repository
npx -y tieline@latest init

Restart or reload the selected agent, then ask it to use the installed tieline skill. In Claude Code, run /tieline; in Codex, run $tieline. Other supported agents can activate the skill from the same natural-language request. That invocation is the semantic-onboarding handoff.

The same setup remains prompt-free for automation:

npx -y tieline@latest init /path/to/product-repository \
  --database offline \
  --embedding local \
  --description "A concise description of the product and business" \
  --context docs/product-context.md \
  --skip-skill-install \
  --yes

Prompt-free setup requires at least one explicit --agent, or --skip-skill-install when no agent should receive the skill. --skill-scope defaults to project. To initialize and install tieline for multiple agents:

npx -y tieline@latest init /path/to/product-repository \
  --database offline \
  --embedding local \
  --yes \
  --agent codex \
  --agent claude-code \
  --skill-scope project

Interactive init does not ask for a product description or context inventory; the installed tieline skill discovers README, product documentation, public code entry points, and tests during semantic onboarding. Automation can still provide known product framing with --description. Additional context sources are optional and explicit: provide each one with a repeatable --context flag. A local source must already exist in the repository, while a website must use an explicit http:// or https:// URL. Init records local sources by repository-relative location rather than generating or copying them. A durable product-context file can hold business purpose, actors, domain terms, invariants, and glossary entries. It should describe the business, not ideas, feature requests, or a second backlog.

Tieline also auto-detects the code directories used for mapping coverage and records them as the Code scope—for example, apps and packages. Most users do not need to configure this. Use a repeatable --source-root only when the repository uses code directories Tieline did not detect. The stored configuration name for this code scope is repository.source_roots.

Choose the database mode based on the workflow:

ModeBehavior
offlineWrites the workspace and supports local YAML/manifest authoring; Observations, Backlog Items, planning Stories, and semantic matching need a database

What lives where:

LocationContents
.tieline/ in the repository (committed, PR-reviewed)Product identity and context (config.json), the contract YAML (spec/), the compiled manifest (manifest/)
PostgreSQL (optional: local Docker, existing, or provisioned)A synced, queryable copy of the accepted contract, plus Observations (feature requests, ideas, bugs), Backlog Items, planning Stories and revisions, and semantic search embeddings
Private profile outside the repository (~/.config/tieline/)Database credentials and clone-local setup state — never committed, never shared through git
localCreates or reuses a dedicated Docker PostgreSQL + pgvector database and stores clone-local credentials privately
existing (hosted / remote)Connects a hosted or remote Postgres 16 + pgvector database identified by DATABASE_URL_ADMIN; no Docker container is required

--embedding hash is deterministic and intended only for development and tests, so it is not offered during interactive onboarding. For a real deployment, choose local, openai, or supabase-edge. In existing (hosted / remote) mode, the baseline defines the least-privilege roles as NOLOGIN. Before init, provide URLs for operator-managed login roles that inherit tieline_reader, tieline_planning_writer, and tieline_repository_sync; init does not create or rotate passwords unless --provision-roles explicitly asks it to. That flag assigns generated login passwords to the tieline roles directly, which is how the agent-driven provisioning path (a freshly created Neon project, for example) reaches a working setup from DATABASE_URL_ADMIN alone. Tieline is provider-neutral: a local Postgres installation, Neon, Supabase, RDS, or any other managed Postgres with pgvector enabled works. It reads DATABASE_URL_ADMIN from the environment or a local .env; credentials are never accepted as CLI arguments. Provisioning tools that synchronize .env files are picked up automatically. Init writes shared product identity, configured context, code scope, contract paths, and runtime defaults to .tieline/config.json. It also registers the tieline MCP server with each selected coding agent: .mcp.json at the repository root is always created or updated, and Claude Code and compatible hosts load it automatically on the next session. Selecting Cursor, GitHub Copilot, Gemini CLI, or OpenCode additionally maintains .cursor/mcp.json, .vscode/mcp.json, .gemini/settings.json, or opencode.json. Unrelated server entries in those files are preserved, and a file that fails to parse is left untouched and reported instead. Codex keeps MCP configuration in a global ~/.codex/config.toml, so selecting Codex runs codex mcp add with the absolute repository path; if the Codex CLI is unavailable, init prints the exact command to run later. Init also writes .tieline/review.html, a self-contained page for browsing the authored capabilities, Stories, and Acceptance Criteria in a browser instead of raw YAML. tieline contract compile regenerates it whenever the contract changes, and a nested .tieline/.gitignore keeps the derived page out of commits. Clone-local setup state and credentials live in a private profile outside the repository, so a new clone completes its own runtime setup instead of inheriting another machine's "ready" state.

On a new repository, the only Tieline command a user needs to begin onboarding is tieline init. It captures deterministic setup, then asks which coding agents should receive the packaged tieline skill. That one skill owns both first-time semantic onboarding and ongoing authoring/reconciliation; a separate onboarding skill is not required. Tieline does not auto-detect or launch an agent, persist agent choices in shared configuration, or invent generic starter content.

Interactive setup offers Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode, and Windsurf. Choose project to install for this repository or global to install for the current user. Project scope is the interactive default. Cancelling agent selection stops initialization before anything is written. Headless callers can use --skip-skill-install to explicitly suppress installation.

--agent IDCoding agent
claude-codeClaude Code
codexCodex
cursorCursor
gemini-cliGemini CLI
github-copilotGitHub Copilot
opencodeOpenCode
windsurfWindsurf

For a project-scoped install, Tieline creates the selected agent's project marker when the repository is fresh, then delegates skill installation to Skillfish. It invokes the latest installer through npx, against Tieline's public default branch and without adding Skillfish as a package dependency. A single-target project invocation has this shape:

npx --yes --package=skillfish@latest skillfish add knoxgraeme/tieline \
  --path skills/tieline \
  --agent "Codex" \
  --project \
  --yes \
  --json

The installed skill runs semantic closeout before implementation handoff, commit, push, or pull-request creation and updates. It classifies each changed behavior cluster, directly updates and compiles justified contract changes, and reruns if the implementation diff changes. The pull-request diff is the review surface; the agent does not stop at a comment and wait for separate approval to write the contract. The deterministic Contract workflow still validates the result and never invokes a model or authors branch changes.

If a requested install fails or does not finish within two minutes, the workspace and private runtime profile remain ready. Tieline terminates the installer, exits non-zero, and prints a retry command using its stable agent IDs, for example:

npx -y tieline@latest init . --yes --agent codex --skill-scope project

The MCP server is registered with the exact Tieline version that ran init, so hosts use the same published package without requiring a global install or silently changing versions. Rerun npx -y tieline@latest init . to upgrade repository-local pins; repeat any --agent options for hosts configured outside the repository. The checked-in configs keep TIELINE_WORKSPACE at ".", which resolves against the host's working directory. Hosts that keep MCP configuration outside the repository and have no registration CLI (Claude Desktop, Windsurf) need a manual entry with the same exact version and the absolute repository path:

{
  "mcpServers": {
    "tieline": {
      "command": "npx",
      "args": ["-y", "tieline@<installed-version>", "serve"],
      "env": { "TIELINE_WORKSPACE": "/absolute/path/to/repository" }
    }
  }
}

The installed tieline skill (/tieline in slash-command agents and $tieline in Codex) and the equivalent tieline MCP prompt are two delivery surfaces for the same maintained semantic workflow. The MCP prompt is a reusable instruction template exposed by the Tieline server; retrieving it loads the workflow into the conversation, while MCP tools remain the operations the agent calls. Existing MCP clients can continue to request the deprecated tieline_author prompt name; it returns the same content. That workflow can:

  • shape a planning Story/AC or Backlog Item in Postgres;
  • semantically onboard an empty spec from configured descriptions, local context, repository docs, code entry points, and tests;
  • start implementation from a Story, AC, Backlog Item, Observation, or branch;
  • reuse an existing definition, add an alias, or intentionally create a new ID;
  • materialize planning IDs into repository YAML;
  • reconcile branch changes, compile the manifest, and summarize semantic and mapping-coverage changes.

An empty .tieline/spec/ immediately after init is intentional: init does not invent generic capabilities. The authoring skill validates the detected code scope against the repository before claiming coverage. While the spec has no Stories, tieline status --json exposes onboarding.required, the tieline skill name, its direct invocation instruction, and npx -y tieline@latest init . as the install command. onboarding becomes null after the first Story exists. Status also reports whether the local profile is ready and whether database-backed semantic matching and planning writes are configured. Tool calls remain the operational check.

Before creating planning work, machine matching searches existing Stories, ACs, Backlog Items, and similar Observations. It presents candidates and requires an explicit reuse-or-continue choice. Each candidate reports its raw ranking features and the admitted_by signals that cleared the absolute magnitude floor; the blended score only orders admitted candidates. Similarity never confirms a relationship. Raw Observations remain append-only even when duplicate language is consolidated. In offline mode, authoring searches local YAML and the compiled manifest and explicitly reports that organization-wide duplicate checking was unavailable.

Validate and compile without a database:

tieline contract validate .
tieline contract compile .
tieline contract coverage . --json

When an asset locator or Acceptance Criterion ID is already known, read its exact reviewed context before editing or using semantic discovery. Asset mode accepts a repository-relative path plus optional code/test kind and canonical selector; AC mode accepts one stable ID:

tieline contract context --path src/contract/impact.ts \
  --kind code --selector function:analyzeContractImpact
tieline contract context --ac CONTRACT-001-AC3 --json

The equivalent read-only MCP tools are get_asset_intent_context and get_acceptance_criterion_context. Both CLI modes and MCP tools answer from the compiled manifest without Postgres, embeddings, or network access. Results include the stable repository key and a content-derived manifest_digest for the reviewed contract that answered.

Asset context returns has_context, no_criteria, or not_found. A selector-qualified query includes exact-selector and file-level claims while excluding claims for other selectors in the same file; a path-only query keeps every claim's full kind, repository, path, selector, and framework-hint identity. AC context returns the exact Capability, Story, AC, scenarios, direct links, and Story-fallback links. Both entry points stop after one AC-mediated hop. The associated code and tests are an intent neighborhood and their shared AC links are contract coupling; they are not a runtime dependency graph or a comprehensive blast radius.

Each returned claim reports authored provenance, direct or Story-fallback link scope, content freshness, locator resolution, and semantic support separately. resolved or current means only that structural inspection succeeded; unresolved, not_checked, broken causes, and unknown cross-repository states remain explicit. Semantic support is always not_assessed in these reads. No state proves the criterion is implemented correctly, and a linked test is an evidence locator—not a receipt that the test ran or passed.

Derived code topology and blast radius

Tieline can separately derive a conservative code topology from repository source. This does not replace the authored contract and does not use a graph database. Developers explicitly compile one thin, reviewable .tieline/topology/graph.json; local and historical reads select that file without parsing source or writing files. PostgreSQL can hold the richer, queryable projection of an accepted main generation. Local compilation never writes it. The compiled manifest remains the authority for business intent.

The repository artifact retains a thin traversal projection: file hashes, locator-bearing symbols, adjacency, and unresolved dependency frontiers. Parser diagnostics, source ranges, reference facts, and resolved explanations remain available in committed PostgreSQL generations but are not duplicated in the artifact.

The two storage forms have separate operational roles:

StoreRoleUpdate boundary
.tieline/topology/graph.jsonDeterministic, repository-local traversal snapshot for review and Git historyExplicit tieline code compile; commit it with the source change
PostgreSQL topology tablesRich shared projection for hosted reads of accepted codeA protected repository publisher after merge to main

They identify the same derived generation but are not competing authorities. graph.json contains no Story or AC bodies; trace and blast radius join its code locators to the matching compiled manifest at read time. PostgreSQL keeps relational source ranges, references, resolutions, and diagnostics that would only bloat the reviewed file.

This release defines the relational schema and repository but does not attach topology publication to the existing repository-sync command. Until that merge-only publisher is added, code compile writes only graph.json and hosted topology is available only when a trusted integration explicitly persists a complete generation.

# Explicitly derive the artifact after selected source or resolver changes.
tieline code compile . --json

# Verify integrity and freshness without parsing or writing.
tieline code validate . --json

# Follow statically derived imports from one exact symbol.
tieline code trace --path src/commands/code-topology.ts \
  --selector function:executeDependencyTrace --direction dependencies --json

# Find code that may depend on changes since a Git base, then join visited
# locators to authored AC claims. The default direction is dependents.
tieline code blast-radius --base origin/main --json

The equivalent read-only MCP tools are trace_code_dependencies and analyze_code_blast_radius. CLI and MCP delegate to the same domain results. Local reads need no database and never compile or silently repair topology. Missing, stale, incompatible, invalid, over-capacity, and unsafe artifacts are named nonzero outcomes with an explicit compile remediation only for mutable workspace state. Historical reads load the topology and, for blast radius, the manifest from the same resolved commit. A hosted dependency trace can continue to select a compatible complete Postgres generation when no checkout is available.

Supported structural facts are intentionally narrower than each language:

LanguageParsed symbols and module formsConservative resolution
JavaScript, JSX, TypeScript, TSXClasses, functions, methods, interfaces, types, enums, namespaces, top-level bindings, static imports, exports, re-exports, and literal dynamic importsRelative files with supported extensions and index files, static baseUrl/paths aliases, and named exports/re-exports
PythonClasses, functions, methods, import, from ... import, relative imports, and public top-level exportsRepository and statically declared source roots, modules, packages, and named public symbols
RustStructs, enums, traits, types, modules, functions, constants, statics, impl owners/methods, mod, use, pub use, and grouped pathsStatic Cargo crate roots, conventional module files, and crate, self, and super paths
SQLConservative top-level table, view, and function declarations with safely representable namesNot yet supported; SQL object references do not produce dependency edges or frontiers

Dynamic module names, glob imports, generated modules, unsupported or non-static configuration, external packages/crates, conditional package exports, and multiple possible targets remain named unresolved, external, or ambiguous frontiers. Tieline never guesses an exact edge for them. Parser recovery and capture truncation are also explicit.

Every fact is tied to immutable source bytes and records zero-based UTF-16 code unit offsets plus zero-based UTF-8 byte offsets; line and column values use the same named coordinate systems. Persisted compatibility includes the pinned parser/grammar set, normalized query contract, resolver implementation and configuration digest, topology schema, and fact policy. Incompatible generations are refused rather than silently mixed.

Traversal locates an exact repository path and optional canonical selector before walking. Defaults are depth 4, 500 visited nodes, 2,000 edges/frontiers, and 100 returned paths. Hard maxima are depth 8, 1,000 nodes, 4,000 edges/frontiers, and 200 paths. Results are cycle-safe and report each independent truncation reason. Code paths are labeled derived_code_dependency; authored joins are contract_coupling and say only may_be_impacted with semantic_support: not_assessed. Two files sharing an AC do not thereby depend on one another, and no topology result proves that an implementation satisfies an AC or that a linked test passed.

Use semantic discovery only when the exact path, selector, or AC ID is unknown. For the compatibility path-to-AC list without selector-aware neighborhood context, ask which criteria the reviewed manifest records:

tieline contract criteria src/commands/check.ts src/server.ts

This is an exact path lookup, not semantic search. Each path is reported as has_criteria, no_criteria, or not_found; results with criteria preserve whether the link is direct on an acceptance criterion or a story_fallback. JSON output also carries a content-derived manifest_digest identifying the complete reviewed manifest that answered.

Compilation writes .tieline/manifest/, one file per capability plus a small index:

.tieline/manifest/
  index.json        schema version and the stable repository key
  CONTRACT.json     one capability, named after its stable ID, with the
  RETRIEVAL.json    specification file and hash it was compiled from
  ...

A capability is exactly one specification file, so this is the boundary the contract already has. The schema-v2 index contains only stable repository identity, stays byte-identical for commit-only changes, and uses normal Git merging. Different capability shards avoid cross-capability conflicts; edits to the same shard use normal conflict resolution. Compiling deletes stale capability shards the specification no longer declares.

Mapping coverage counts a repository file as mapped when any contract link names it. That records who claimed the file is evidence, not how much is known about the claim, so coverage also reports a confidence tier. Each mapped file counts once, at the highest tier it reaches:

TierWhat is knownWhat it does not establish
assertedA link names the file. A human said so.That anything was measured at all
hash_currentThe file still hashes to the content recorded in the reviewed manifest.That the review was right, or that the file still does what the criterion says

The tiers are additive. eligible_files, mapped_files, unmapped_files, and percentage keep their existing meaning, and the tier percentages use the same denominator, so they sum to percentage. With no hash comparison available, every mapped file reports asserted and the numbers are unchanged.

hash_current compares against .tieline/manifest/ when that manifest is readable and belongs to this repository, because the reviewed manifest is the only record of the content a reviewer accepted. Without it, coverage compiles the manifest from the working tree, where the reviewed hash is the hash it just measured and no drift is observable. Story-level and criterion-level links are treated alike here: a link names a file whatever its scope, so either can carry the reviewed hash that lifts the file to hash_current.

Ask which links a human should re-read:

tieline contract link-review .

Link review scores each criterion-level code and test link on lexical overlap between the acceptance criterion's prose and the linked file's names, comments, and string literals, then reports the weakest links in the repository's own distribution. This is inference, never evidence. It never confirms a relationship and never refutes one; each candidate carries a rationale naming the terms that did and did not overlap so a reviewer can judge the suggestion instead of trusting a number. An empty candidate list means the heuristic is not asking for attention, not that the links are correct. Missing files are left to tieline check and are reported as skipped rather than scored. The command is advisory and exits zero.

Ask an agent to judge the branch's contract evidence:

tieline contract grade . --base <base-ref> --emit-scope --json
tieline contract grade . --base <base-ref> --verify <verdicts.json>

The first command deterministically emits every changed acceptance-criterion link to grade and the exact symbol citations allowed for it. A link enters the scope when either of its sides changed against the base: the artifact side — the linked file was modified, added, renamed, or deleted — or the claim side — the link is new, belongs to a new criterion, or its criterion was re-worded, even when the linked file is untouched. A base with no manifest is the initial contract, so onboarding's links are all in scope as link_added.

For JavaScript, JSX, TypeScript, TSX, Python, Rust, and SQL source, each scope entry also carries ephemeral code_evidence from Tieline's Tree-sitter analyzers: the analyzed content hash and parser compatibility, diagnostics, and bounded source evidence for each legal declaration. symbols remains the complete, closed citation allow-list. An explicit link selector must exactly match one canonical parser selector and limits the entry to that declaration. A link without a selector offers only unique canonical top-level or owner-aware declarations; comments and local variables do not become citations. Missing, unreadable, oversized, unsupported, or structurally incomplete source—or an invalid, unresolved, or ambiguous explicit selector—instead produces unavailable evidence and an empty allow-list.

SQL evidence is deliberately narrow in this increment: it identifies conservative top-level table, view, and function declarations when their names can be represented safely. SQL object references and dependency edges are not yet derived, so SQL symbols can be linked to Acceptance Criteria without being treated as SQL blast-radius coverage.

The agent inspects the evidence and artifact and assigns supported, partial, or unsupported; parser evidence establishes which current declaration may be cited, not whether its implementation semantically satisfies the criterion. Grade IDs bind the exact criterion text and current source/parser evidence, so verdicts become stale after either the criterion or source changes. The second command verifies that every verdict belongs to the current scope and that every claimed citation came from its allow-list. Tieline does not call a model, database, or network or persist grades for this workflow. Verification is advisory by default, including negative results; add --strict to the verify command only when unsupported evidence should fail the gate. The installed tieline skill carries this grading workflow as an internal reference and dispatches fresh grading contexts so authors do not judge their own rationale.

Generate a human-readable browser review of the accepted YAML:

tieline contract review .

This writes .tieline/review.html, a self-contained page with capability navigation, Story and AC cards, scenario steps, evidence links, search, lifecycle filters, and a print layout. Open the file directly in a browser. Use --output <path> to write it elsewhere.

CI can check affected ACs:

tieline check --base <base-ref> .

Use the comparison ref supplied by the caller when available. Otherwise, agents should determine it from repository metadata, preferring the remote-tracking default branch, and ask only when it cannot be determined; do not assume every repository uses origin/main.

The check compares changed, renamed, and deleted paths with manifest locators and reports each affected AC plus its freshness. It also sweeps every link for broken targets, whether or not the diff touched them, because a link can rot without the change under review going near it. The check treats these integrity states differently:

StateCauseEffect
staleThe linked file changed since it was reviewed, or was never reviewed against a recorded hash. Whether the AC still holds needs a human.Warning, exit 0
brokenThe linked path is missing, is not a file, or resolves outside the repository.Error, exit 1
stale manifestThe committed manifest differs from what the current contract compiles to.Error, exit 1

Broken links fail the check because deciding they are wrong needs no judgement: the manifest points at evidence that is not there. Pass --no-fail-on-broken to downgrade broken links to warnings and exit zero. A stale manifest also fails by default: run tieline contract compile ., review the semantic diff, and commit the result. Use --no-fail-on-stale-manifest only when intentionally downgrading that integrity gate to a warning. Invalid YAML or an unreadable manifest fails because no trustworthy result can be computed. See the GitHub Actions example.

After merge, run:

tieline contract sync . --expected-previous-commit <previous-main-sha>

Sync is idempotent and checkpointed. A delayed job cannot overwrite a newer projection. If planning changed while a materializing pull request was open, the merged repository version wins and the later planning revision is preserved as a handoff conflict for reconciliation.

MCP tools

Reads:

ToolPurpose
search_knowledgeCross-type semantic search with a required retrieval profile and optional typed context
find_relatedEngineering-oriented semantic discovery with applied profile metadata
query_storiesExact Story/AC lookup by authority, lifecycle, IDs, or locators
get_asset_intent_contextExact selector-aware asset-to-intent neighborhood from the compiled manifest; no database required
get_acceptance_criterion_contextExact AC-to-associated-assets neighborhood from the compiled manifest; no database required
get_path_criteriaExact path-to-AC lookup from the compiled manifest; no database required
get_backlog_itemRead a Backlog Item revision and its complete Observation/Story/AC link set
list_handoff_conflictsRead unresolved or historical planning-to-repository conflicts
find_helpSearch ingested external help content
get_help_articleFetch selected help bodies by source + external_id
list_attribution_suggestionsReview machine suggestions and their provenance

Evidence and planning writes:

ToolPurpose
record_observationAppend a request, bug, or question, then return suggestions
decide_attributionConfirm or dismiss an Observation relationship
create_backlog_item, update_backlog_itemManage optional work records after reading their current revision
set_backlog_item_linksReplace Observation and Story/AC targets atomically
create_planning_story, update_planning_storyShape backlog Stories and ACs
decide_attribution_suggestionConfirm or dismiss a machine suggestion

External help content

Help articles remain DB-native rather than being copied into repository YAML. Set DATABASE_URL_SYNC, then import a JSON array, an {"articles": [...]} object, or one article per line in a .jsonl file:

[
  {
    "source": "intercom",
    "external_id": "retrieval-profiles",
    "title": "Choose a retrieval profile",
    "summary": "How support and engineering views differ.",
    "url": "https://help.example.com/retrieval-profiles",
    "markdown": "Use the support profile for production-only answers."
  }
]
tieline import-help ./articles.json --batch-size 50

Batch size may be 1–200. The command writes articles.json.import-report.json after a complete import. Contracts refer to articles by stable source + external_id; imported bodies and metadata stay in Postgres, while YAML may optionally repeat the public URL for review.

Retrieval profiles

Every search_knowledge call names a profile. Explicit filters are additional constraints and cannot broaden it.

ProfileIntended view
supportRepository-owned production Stories/ACs and confirmed evidence
engineeringRepository-owned in-progress, production, and retired context
discoveryPlanning and repository contract, Backlog Items, and Observations
allFull corpus permitted by the connected database role

Use get_asset_intent_context for a known path or selector and get_acceptance_criterion_context for a known AC stable ID before semantic search. Use get_path_criteria for the compatibility path-to-AC list without the selector-aware neighborhood. Use query_stories for broader exact filters such as lifecycle, authority, or capability. Use find_related for shorter engineering-oriented semantic discovery and search_knowledge for heterogeneous retrieval only when exact identity is unknown or the caller needs explicit profile selection and narrowing filters.

An MCP search_knowledge input can carry a reusable Story/AC anchor and artifacts from the caller's current task:

{
  "query": "why are support searches production-only?",
  "profile": "engineering",
  "context": {
    "anchor": {
      "kind": "acceptance_criterion",
      "repository": "tieline",
      "stable_id": "RETRIEVAL-001-AC1"
    },
    "artifacts": [
      {
        "kind": "code",
        "repository": "tieline",
        "path": "src/tools/search-knowledge.ts"
      }
    ]
  },
  "limit": 10
}

Responses include the profile version and each result’s authority/lifecycle or planning state, attribution state when applicable, coverage, freshness, applied retrieval signals, ranking features, and reader-facing match reasons. An optional context can name an Observation, Backlog Item, Story, or AC anchor and/or code, test, or help artifacts. Context reranks only the candidate set already allowed by the profile and filters. Artifact overlap and confirmed graph proximity appear in each result’s ranking features; suggested and dismissed relationships do not create proximity or become confirmed through search. Each result also includes a typed context_anchor when it can be used directly in a follow-up search. Callers can inspect the scores without Tieline claiming that an unresolved artifact locator was applied.

Lexical retrieval is always on. English full-text search covers semantic prose, while pg_trgm identifier matching recalls stable IDs, aliases, code/test paths, selectors, and external help identifiers that stemming handles poorly. Vector similarity is added when an embedding provider is available. Reciprocal rank fusion combines the available lexical and vector rankings with exact alias, artifact-overlap, and confirmed graph-proximity signals, so a missing embedding backend does not turn search into an error. Absolute vector, lexical, or exact alias magnitude determines whether a candidate is credible enough to present; the blended rank-fusion score orders those admitted candidates but does not filter them through a second fixed cutoff.

Graph proximity traverses structural links, repository-declared relationships, and confirmed attributions up to three hops. The graph feature decays from 1.0 at the anchor to 0.75, 0.5, and 0.25; records beyond three hops receive no graph boost. The bound covers useful chains such as Observation → Story → AC → Scenario while keeping broad, weakly related graph neighborhoods from dominating semantic relevance.

Profiles are versioned:

tieline profile list --json
tieline profile put \
  --key support \
  --file ./support-profile.json \
  --created-by maintainer

Coverage, freshness, and mapping

Implementation-link, test-link, and help-link coverage are independently none, partial, or complete for repository-owned Stories. Only direct AC links count; Story-level fallback links remain searchable.

Freshness compares linked repository content with the reviewed manifest hash. It does not claim that a test ran or passed. Test execution receipts are deliberately deferred beyond the MVP.

Repository mapping coverage uses the configured code scope (repository.source_roots) and exclusions as its denominator. Reports include both the percentage and every unmapped eligible file. Path coverage and behavioral correctness remain separate. When no eligible files exist, coverage is null with status=no_eligible_files; it is never reported as 100%.

Configuration

Copy .env.example and set only the credentials needed by the process:

VariableResponsibility
DATABASE_URLRead-only contract, evidence view, profiles, and search
DATABASE_URL_WRITEPlanning Stories/ACs, Observations, Backlog Items, suggestions
DATABASE_URL_SYNCRepository authority transfer, projection, help ingestion
DATABASE_URL_ADMINOffline migrations, profile publication, retention

The MCP server uses read and planning-write connections. Sync/admin credentials belong to explicit CLI/CI operations and should not be exposed to ordinary agents. The packaged migrations must run with an administrative database role. The baseline installs the vector, pgcrypto, and pg_trgm extensions and creates the three Tieline runtime roles. Managed Postgres environments may require an administrator to preinstall pgvector/Postgres contrib extensions or grant the equivalent CREATE EXTENSION and CREATE ROLE capabilities before tieline migrate runs.

Choose one embedding provider:

ProviderConfiguration
localKeeps text local; install the optional runtime during init with --install-local-embedder
openaiSet EMBEDDING_BASE_URL and EMBEDDING_API_KEY; the endpoint must return 384-dimensional vectors
Supabase Edge Function (supabase-edge)Set SUPABASE_URL and SUPABASE_ANON_KEY
hashDeterministic development/test provider; do not use for semantic quality

When Tieline is already initialized, rerun init with --embedding local --install-local-embedder to install the local runtime in Tieline's private runtime directory. Container builds can instead use --build-arg WITH_LOCAL_EMBEDDER=true.

Remote embedding providers receive canonical semantic text or the caller’s query, not raw Observation payloads, external URLs, audit metadata, lifecycle metadata, or repository locators. Use EMBEDDING_PROVIDER=local to keep semantic text local, or hash only for deterministic development tests.

Run the MCP server

Start the transport expected by the MCP host:

tieline serve --stdio
tieline serve --http

HTTP binds to 127.0.0.1:3000 by default and exposes MCP at POST /mcp and liveness at GET /health. Tieline does not provide end-user authentication. Binding to a non-loopback host therefore requires HTTP_TRUST_PROXY=true, at least one comma-separated HTTP_ALLOWED_ORIGINS entry, and an authenticated TLS gateway in front of the server.

Docker

The image defaults to HTTP mode:

docker build -t tieline .
docker run --rm -p 3000:3000 \
  -e DATABASE_URL=postgresql://... \
  -e DATABASE_URL_WRITE=postgresql://... \
  -e EMBEDDING_PROVIDER=openai \
  -e EMBEDDING_API_KEY=... \
  -e HTTP_HOST=0.0.0.0 \
  -e HTTP_TRUST_PROXY=true \
  -e HTTP_ALLOWED_ORIGINS=https://mcp.example.com \
  tieline

Run migrations separately with DATABASE_URL_ADMIN; do not expose that credential to the serving container. For a stdio-only container host, override the image command with node dist/cli.js serve --stdio and set TRANSPORT=stdio so the HTTP health check is disabled:

docker run --rm -i \
  -e TRANSPORT=stdio \
  -e DATABASE_URL=postgresql://... \
  -e DATABASE_URL_WRITE=postgresql://... \
  tieline node dist/cli.js serve --stdio

Data durability and privacy

Repository-owned definitions and their review history are durable in Git. Planning revisions, raw Observations, Backlog Items, retrieval profiles, attribution decisions, help content, conflicts, and audit events originate in Postgres and require normal database backups. Rebuilding the repository projection alone cannot recreate them.

Observation payloads may contain customer or operational data. Store the minimum useful source text and retain the source-system pointer; ordinary MCP reads use sanitized Observation projections. Retention or redaction requires a privileged administrative workflow rather than the read or planning-write connection.

Verification

npm run build
npm test
npm run test:tieline

npm test runs every offline suite: contract schema, manifest, contract command, impact, link plausibility, reconciliation, path criteria, grading, ranking, retrieval, embeddings, HTTP transport, MCP smoke, evidence, contract reads, and the migration baseline. npm run test:tieline builds the CLI and exercises workspace onboarding end to end. Individual suites remain available as npm run test:<name>.

Database integration tests require a disposable blank Postgres database with pgvector and an administrative URL with the migration privileges described above:

DATABASE_URL_ADMIN=postgresql://... npm run test:integration

The current baseline is intentionally breaking: pre-release databases from the earlier model must be recreated rather than upgraded in place.

Project structure

PathPurpose
src/contract/YAML schemas, loading, validation, and manifest compilation
src/tools/MCP read, evidence, and planning tools
src/adapters/postgres/Least-privilege persistence and semantic retrieval
src/tieline/Repository initialization, profiles, status, and setup
migrations/PostgreSQL/pgvector schema and role baseline
scripts/Contract, retrieval, transport, and integration verification
skills/tieline/Packaged onboarding, authoring, grading, and reconciliation workflow
.tieline/This repository's own accepted contract and compiled manifest

License

MIT

FAQs

Package last updated on 15 Aug 2026

Related posts