non-linear-docs/07-GLOSSARY-AND-DECISIONS.md

6.7 KiB

Non-Linear: Glossary & Key Decisions

Glossary

Term Definition
Node Any entity in the graph — either a component or an issue.
Component A structural node representing part of the system (service, module, directory). Maps to code.
Issue A work node representing something to be done (task, bug, feature). Flows through statuses.
Decomposition Tree Strict parent→child hierarchy. The structural spine of a project.
Lateral Link Typed edge between nodes that doesn't affect hierarchy. Types: blocks, relates_to, duplicates, depends_on.
Backlink Inbound lateral link surfaced on a node ("3 tasks blocked by this").
Repo Link Association between a component node and a repository/directory in a VCS.
Skeleton The component tree — stable structure that mirrors the codebase.
Skeleton Inference Fast-start: connect repos, AI proposes component tree from code structure.
Layered Overview Primary graph view showing nodes in rows by tree depth.
Focus Widget Detail view showing one node with parent, children, breadcrumbs, and history.
Actor Any entity that can perform actions: human user or AI agent.
Policy Single permission rule: actor + action + resource scope + effect (allow/deny).
Role Named, reusable bundle of policies. Convenience layer over granular engine.
Resource Scope Where a policy applies: global, subtree, or single node.
Subtree A node and all of its descendants in the decomposition tree.
Reparenting Moving a node to a different parent. Structural change that affects permissions.
Opaque Link Lateral link whose target is outside actor's permission scope. Link visible, details withheld.
Root Node Top-level node of a project's decomposition tree.
Depth Node's distance from root. Root = 0, its children = 1, etc.
Inbox Staging area for issues without a parent. Triage = assigning a parent.
Cycle Named set of issue references + date range. Temporal view over spatial tree.
Plan-then-apply Preview of consequences before structural changes are committed.
Command Palette Cmd+K unified entry point for actions, search, and navigation.
Component Health Derived status for components — aggregated from children's statuses.

Key Architectural Decisions

1. Two Node Types: Components and Issues

Decision: The graph has two explicit types instead of untyped depth-as-type.

Rationale: Code repositories have inherent structure — repos, packages, modules, directories. If the system infers a skeleton from code, it needs to distinguish structural nodes (components) from work nodes (issues). A component at depth 3 is still a component. An issue at depth 1 is still an issue. Type is orthogonal to depth.

Trade-off: More rigidity than untyped model. Mitigated by keeping the type set minimal (just two) and allowing flexible nesting within each.

2. Two Separate Graphs

Decision: Decomposition tree and association graph are explicitly separated.

Rationale: Jira unifies parent/child and other link types, making neither clean. Separating them means the tree is always valid, reparenting is a distinct operation, and lateral links can be added/removed without structural impact.

3. Repository Integration as First-Class Feature

Decision: Multi-repo support with component↔repo linking and skeleton inference from day one.

Rationale: The cold-start problem kills structured tools. "Connect your code and we'll infer the skeleton" eliminates the biggest adoption barrier. It also makes code integration features (commit association, PR surfacing) dramatically better because the system knows which code maps to which component. This is the strongest differentiator vs. Linear/Jira.

4. Skeleton Inference (AI-Assisted Fast-Start)

Decision: When connecting repos, AI proposes a component tree from code structure, user adjusts and confirms.

Rationale: Manual component creation is slow and error-prone. Code structure is already a graph — package manifests, directory layout, module boundaries. Inferring the skeleton from code gives users a 90% starting point in seconds. The "adjust" step ensures human control.

5. Granular Policies from Day One

Decision: Full policy engine (actor + action + resource scope) in v0.1.

Rationale: The agent story requires fine-grained, resource-scoped permissions. Roles make it simple for users who don't need custom policies.

6. Resource Scope = Graph Position

Decision: Permissions scope to subtrees in the decomposition tree.

Rationale: The graph is the namespace. "Backend API subtree" = the component and everything under it. Permission management becomes visual.

Decision: When an actor can see node A but not node B, a link A→B is visible (type shown) but B's details are withheld.

Rationale: Agents need to know about blockers even without full access.

8. Default Deny

Decision: If no policy explicitly allows an action, it is denied.

Rationale: Safer default for agents.

9. Agents as First-Class Actors

Decision: Agents have their own accounts with distinct identity in logs and UI.

Rationale: Traceability. "deploy-bot changed status" vs. "John (via script) changed status."

10. Keyboard-First Interaction

Decision: Command palette is primary navigation. Every action has a shortcut.

Rationale: Graph navigation has more dimensions than a flat list. Borrowed from Linear.

11. Plan-Then-Apply for Structural Changes

Decision: Reparenting, deletion, bulk operations show preview before committing.

Rationale: Structural changes cascade — permissions shift, links break, agents lose scope. Borrowed from Terraform.

12. Triage Inbox (Rootless Nodes)

Decision: Issues without a parent live in inbox. With repo integration, triage gets smart suggestions.

Rationale: Decouples "capture" from "organize." Smart triage uses code context to suggest the right component.

13. Dual Database (Neo4j + Postgres)

Decision: Neo4j owns graph topology. Postgres owns content and metadata. Linked by UUID.

Rationale: Cypher handles the graph queries Non-Linear needs. Clean separation of concerns.

Decision: A new lateral link type specifically for inter-component dependencies.

Rationale: With repo integration, component dependencies can eventually be inferred from code (import graphs, API calls). This is a distinct semantic from issue-level "blocks" — it represents architectural coupling, not work sequencing.