Skip to content

ArchSpine Git Artifact Strategy

This document defines how ArchSpine should treat .spine/ artifacts in a host repository, and how spine init should shape the default Git experience.

Problem

The current product surface is inconsistent:

  • repository root .gitignore ignores local runtime state
  • repository root .gitattributes marks generated snapshot files as generated
  • examples/demo-project/.gitignore ignores almost the entire .spine/ tree
  • spine publish describes .spine/index/** and .spine/atlas/** as distributable snapshot outputs
  • spine init currently manages .ignore, but not .gitignore or .gitattributes

That creates a product ambiguity: is .spine/ a local cache, a committed governance layer, or a distributable repository artifact?

Product Goal

The goal is to make ArchSpine onboarding clean without collapsing the distribution model.

The default user experience should achieve all of the following:

  1. first-time spine init should not create noisy Git churn
  2. users should understand which .spine files are project assets versus local runtime state
  3. teams should be able to commit distributable semantic snapshots without review noise
  4. init, publish, docs, and demo projects should express one consistent model

The product recommendation is now:

  • Distributable snapshot for the default, team-oriented path
  • Local-first as the lighter opt-out path for personal or experimental use

User Needs

1. Local adopters

Primary need:

  • get value quickly without polluting the repo

Expected default:

  • local runtime noise stays out of Git
  • if the user wants a lighter footprint, they can opt into local

2. Team maintainers

Primary need:

  • integrate ArchSpine into a real repository workflow

Expected default:

  • governance inputs are committed
  • generated outputs have explicit Git semantics
  • review remains readable

3. Distribution owners

Primary need:

  • publish and review semantic snapshot outputs as repository assets

Expected default:

  • distributable outputs can live in Git
  • generated outputs are marked as generated in review tools
  • local runtime state remains excluded

Artifact Model

ArchSpine should formally divide .spine/ outputs into three classes.

1. Control-plane artifacts

Examples:

  • .spine/config.json
  • .spine/rules/**

Properties:

  • human-authored or human-reviewed
  • should be committed
  • should remain normal review targets

2. Local runtime state

Examples:

  • .spine/cache.db*
  • .spine/.lock
  • .spine/protected-output-baseline.json
  • future machine-local cache or lock files

Properties:

  • local execution support only
  • should not be committed by default
  • should be managed by .gitignore

3. Distributable snapshot artifacts

Examples:

  • .spine/index/**
  • .spine/atlas/**
  • .spine/manifest.json
  • .spine/languages.json
  • .spine/diagnostics/** when kept as generated outputs

Properties:

  • generated by ArchSpine
  • may be committed as repository distribution assets
  • should be marked as generated in review tooling
  • should not be silently forced out of Git by default

Product Decision

ArchSpine will treat .spine/ as a repository control plane plus managed generated outputs, not as a pure local cache directory.

That leads to the following default decisions:

  1. spine init should manage .gitignore
  2. spine init should manage .gitattributes
  3. .gitignore should cover local runtime state only
  4. .gitattributes should mark distributable snapshot artifacts as generated
  5. spine init should not, by default, ignore .spine/index/** or .spine/atlas/**
  6. spine publish remains the refresh path for distributable snapshot artifacts

Why Not Ignore All of .spine/

Ignoring most of .spine/ during init would solve short-term local noise, but it would also implicitly redefine product semantics:

  • users would infer that generated snapshot artifacts are not repository assets
  • publish would continue describing those same artifacts as distributable outputs
  • demo projects, docs, and Git behavior would continue to disagree

This is a product contradiction, not a small UX issue.

init Default Experience

spine init should optimize for onboarding, but without breaking the distribution model.

Default behavior:

  1. recommend Distributable snapshot in the interactive artifact strategy picker
  2. create or update a managed ArchSpine block in .gitignore
  3. create or update a managed ArchSpine block in .gitattributes
  4. continue managing .ignore
  5. leave user-owned file content outside the managed blocks untouched

The default should be described as:

  • keep local runtime state out of Git
  • keep distributable semantic snapshots review-friendly

Managed File Strategy

Managed file updates should use bounded blocks instead of full-file replacement.

Requirements:

  1. if the file does not exist, create it
  2. if a managed block exists, update only that block
  3. if the file contains unrelated user content, preserve it and append the managed block
  4. uninit or cleanup flows should remove only the managed block

Proposed Managed Entries

.gitignore

Recommended managed entries:

gitignore
# >>> ArchSpine managed >>>
.spine/cache.db*
.spine/.lock
.spine/protected-output-baseline.json
.spineignore.local
# <<< ArchSpine managed <<<

Rationale:

  • these are local runtime or local-only override artifacts
  • excluding them improves default repo hygiene
  • excluding them does not conflict with publish

.gitattributes

Recommended managed entries:

gitattributes
# >>> ArchSpine managed >>>
.spine/index/** linguist-generated=true
.spine/atlas/** linguist-generated=true
.spine/manifest.json linguist-generated=true
.spine/languages.json linguist-generated=true
.spine/diagnostics/** linguist-generated=true
# <<< ArchSpine managed <<<

Rationale:

  • these are generated outputs
  • generated classification improves GitHub review experience
  • generated classification preserves commit-ability without hiding repository assets

Non-Goals

This proposal does not do the following:

  • redefine scan policy
  • make .spine/index/** or .spine/atlas/** local-only artifacts
  • require every repository to commit distributable snapshots immediately
  • introduce a multi-mode init flow in the first implementation step

Future Extension

If later needed, ArchSpine may expose an explicit artifact strategy mode such as:

  • local
  • distributable

But the first implementation should not block on mode design. The immediate requirement is to make the default semantics internally consistent.

Execution Plan

Phase 1. Product contract alignment

Produce and approve this model as the canonical decision:

  • three artifact classes
  • .gitignore for local runtime state
  • .gitattributes for generated distributable artifacts
  • publish remains the distributable refresh path

Phase 2. Product surface alignment

Update product-facing references so they express the same model:

  • root defaults
  • demo project defaults
  • init help text and onboarding language
  • docs that describe Git behavior and publish semantics

Phase 3. Implementation

Add managed sync utilities similar to current .ignore and agent-instruction sync:

  • syncGitIgnoreFile
  • removeManagedGitIgnoreFile
  • syncGitAttributesFile
  • removeManagedGitAttributesFile

Integrate them into spine init and cleanup flows.

Phase 4. Verification

Add tests for:

  • file creation when missing
  • bounded update when managed block exists
  • append-with-preservation when user content exists
  • cleanup removing only managed entries
  • init state tracking for managed Git files

Acceptance Criteria

The proposal is complete when all of the following are true:

  1. spine init manages .gitignore, .gitattributes, and .ignore
  2. root docs, demo defaults, and CLI language all match the same artifact model
  3. local runtime state is excluded by default
  4. distributable snapshot outputs are not default-ignored
  5. generated snapshot outputs are marked as generated for review tooling
  6. user-owned content in managed files is preserved

Immediate Follow-up Work

After approving this strategy, the next concrete implementation tasks are:

  1. fix the demo project .gitignore to match the product decision
  2. add managed sync helpers and tests
  3. wire them into spine init
  4. update docs that currently imply conflicting Git behavior

English is the primary docs tree; zh-CN mirrors shipped behavior.