跳转至

spec-of-file

A per-edit PostToolUse annotation that fires only when ACTIONABLE — the first edit of an over-owned (> maxOwners) or uncovered file flags it at the edit; a sanely-owned file is left silent.

raw source

spec-first grounds a session once, at its first code access — but on a long session that single nudge scrolls away, and a file's actual owner is invisible at the moment you change it. Keep the contract in view at the edit: when a session edits a file, tell it which spec governs that file. The danger is noise — a per-write announcement over a 50-edit refactor is exactly the signal agents learn to tune out — so it must fire once per file, never per write, and never block.

expanded spec

A PostToolUse hook (spec-of-file.sh), wired on PostToolUse via settingsJson. Like spec-first, it is NOT gated on governed — spec-awareness serves any agent. On the first Edit / Write / NotebookEdit of a given file it emits non-blocking additionalContext naming the file's governing spec; a ledger dedupes so each file is annotated once per session. That ledger is a sibling file in the session's GLOBAL store dir (resolved from the payload's session_id, runtime) — the worktree holds no SpexCode state any more. The ledger key is the repo-relative path after normalization, so an absolute path and a relative path to the same file do not double-speak. Spec files are skipped — not governed code.

The hook only speaks for Git-relevant files inside the current repo. A path outside the repo (for example a tool's /tmp/... transcript), .git, .spec, and ignored untracked files are silent. A tracked file is always eligible, and a new untracked-but-not-ignored repo file is eligible so a brand-new source module can still be told to get a spec home before it drifts. This keeps the annotation from treating shell scratch paths, node_modules, build output, or other ignored artifacts as product files while preserving the uncovered-source warning that matters.

The file→spec resolve is spex owner <path> --actionable (a thin verb in cli.ts, resolver specOwners in specs.ts), a light read of frontmatter code: only — no git walk. --actionable is the discipline: it speaks ONLY when there is something to act on, so the annotation stays rare instead of chatty.

  • over-owned (> maxOwners governors) → "this file does too much — SPLIT it so each governor owns its own module (or merge the nodes, or give it a single foundation owner + relate)." The governed-related guardrail, surfaced live the moment an over-owned file is touched.
  • uncovered (no owner) → give it a home before it drifts.
  • sanely owned (1..maxOwners) → silent. spec-first and the spec-pointer already grounded the agent; re-announcing a known owner on every edit is exactly the noise this annotation must not become — the lesson that an earlier always-on version of this hook taught.

Non-blocking and once-per-file by design: a pervasive signal earns its keep only by staying rare and precise, or it becomes the noise it was meant to cure. The enforcer is still the Stop gate; this annotates.

This node owns both copies of the hook body: the dogfood .config source that governs SpexCode itself and the spex init template that fresh adopters receive. They must move together so the behavior a user installs matches the behavior SpexCode uses on itself.