spec

package
v0.9.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: MIT Imports: 12 Imported by: 0

Documentation

Overview

Package spec implements the topological pillar: cascading, directory-scoped spec bundles. Rules live next to the code they govern, inside .spectackle folders:

.spectackle/spec.md           root scope (repo-wide architecture rules)
<dir>/.spectackle/spec.md     rules scoped to <dir> and everything below

Resolution for a path is root -> ancestor chain top-down -> nearest dir. Deeper files extend the inherited set (union); they win only explicitly:

  • `overrides: [RULE-ID, ...]` in front matter removes inherited rules;
  • `inherits: false` drops everything inherited.

This mirrors how .gitignore/CLAUDE.md cascade, and it is what makes context loading token-efficient: the server materializes only the rules on the root->dir spine of the files in an impact radius, never the whole corpus.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AppendIntent

func AppendIntent(ws workspace.Root, ctx, line string) error

func IntentDebrisMarker added in v0.8.5

func IntentDebrisMarker() string

IntentDebrisMarker exposes intentDebrisMarker so internal/lifecycle can assert its truncation marker still matches the text this package heals.

func RetireRule

func RetireRule(ws workspace.Root, c *Cascade, id string) (string, error)

RetireRule deletes a rule block from its spec bundle; the full text survives in the journal (written by the caller). Returns the file path.

func SpecRel

func SpecRel(ctx string) string

SpecRel returns the repo-relative spec bundle path for a context dir ("" = root).

Types

type AuthorReq

type AuthorReq struct {
	Dir       string                                    // context dir ("" = root)
	Stem      string                                    // ID stem, e.g. "CUDA-KRN"; default: stem of last rule in target file
	ForceID   string                                    // exact ID to use (replay); skips minting, still lints
	Mint      func(stem string, floor int) (int, error) // collision-free minter (swarm coord); nil = local scan
	Sentence  string                                    // composed EARS sentence
	Rationale string
	Applies   []string
}

AuthorReq describes one rule to persist.

type AuthorRes

type AuthorRes struct {
	ID   string
	Path string // repo-relative spec file path

	// Root is the absolute dir Path is relative to: the workspace root
	// AddRule/EditRule were called with, not necessarily the main checkout.
	// GitHub issue 27: a caller inside a linked git worktree got back a
	// bare "ok ID .spectackle/spec.md" that read as if it landed in the
	// worktree, when the write had actually landed in the enclosing main
	// checkout — the relative Path alone can't tell the two apart. Root
	// pins down the other half of that join so a caller (or a future
	// mcpserver reporting change) can print filepath.Join(Root, Path) and
	// never wonder which directory it is relative to.
	Root string

	Findings []ears.Finding
	Written  bool
}

AuthorRes reports the outcome.

func AddRule

func AddRule(ws workspace.Root, c *Cascade, req AuthorReq) (AuthorRes, error)

AddRule lints the sentence and, if error-free, appends it to the context dir's spec bundle (creating the file with front matter when needed) under the next free ID. Lint errors block the write; warnings do not.

func EditRule

func EditRule(ws workspace.Root, c *Cascade, id, sentence, rationale string, applies []string) (AuthorRes, error)

EditRule replaces the block of an existing rule in place: new sentence (lint-gated), rationale and/or applies list. Empty sentence keeps the old one; empty rationale keeps the old one; applies always replaces.

type Cascade

type Cascade struct {
	// contains filtered or unexported fields
}

Cascade resolves the applicable rules for paths and nodes.

func Load

func Load(root string) (*Cascade, error)

Load discovers and parses all spec bundles under root. Parse and lint findings do not fail the load; they are available via Findings().

func (*Cascade) All

func (c *Cascade) All() []SpecFile

All returns every loaded spec file, shallow before deep.

func (*Cascade) File

func (c *Cascade) File(dir string) (SpecFile, bool)

File returns the spec file scoping a context dir, if loaded.

func (*Cascade) Findings

func (c *Cascade) Findings() []ears.Finding

Findings returns all lint findings gathered while loading the cascade.

func (*Cascade) ForNode

func (c *Cascade) ForNode(id, file string) []ResolvedRule

ForNode returns the rules binding a graph node (SPX-SPC-007): rules whose applies list names the node ID come first — explicit bindings are the strongest signal — followed by the cascade rules of the node's file, deduplicated by rule ID.

func (*Cascade) ForPath

func (c *Cascade) ForPath(rel string) []ResolvedRule

ForPath returns the rules applicable to a repo-relative file path, in resolution order (root -> nearest dir). Overrides and inherits:false of deeper files are applied.

func (*Cascade) MaxNum

func (c *Cascade) MaxNum(stem string) int

MaxNum returns the highest number used for a stem across the cascade — the floor for collision-free minting.

func (*Cascade) NextID

func (c *Cascade) NextID(stem string) string

NextID returns the next free ID for a stem, scanning the whole cascade so the result can never collide locally (E006). Cross-worktree uniqueness needs AuthorReq.Mint (coord counters).

func (*Cascade) Rule

func (c *Cascade) Rule(id string) (ears.Rule, bool)

Rule looks up a rule by ID.

type ResolvedRule

type ResolvedRule struct {
	ears.Rule
	ScopeDir string // "." for root, else the context dir
}

ResolvedRule pairs a rule with the directory scope it came from.

type SpecFile

type SpecFile struct {
	Path      string // repo-relative path of the spec.md
	Dir       string // context dir it scopes ("" = root)
	Prefix    string
	Scope     []string
	Inherits  bool
	Overrides []string
	Rules     []ears.Rule
	Sections  []ears.Section
}

SpecFile is one parsed spec bundle.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL