This repository was archived by the owner on Oct 5, 2026. It is now read-only.
Repository navigation
Conversation
Introduces a manifest.json file in .svp/ to track schema and forge versions, enabling forward-compatible schema evolution with automatic migration when users upgrade forge. - Add manifest.ts with SCHEMA_VERSION, read/write, compatibility check - Add migrate.ts with sequential migration runner and registry - Write manifest.json during forge init - Guard all CLI commands that read .svp/ with checkCompatibility() - Auto-create manifest for legacy projects missing manifest.json - Error on downgrade (manifest schema > current forge schema) - Add 13 tests for manifest and migration logic
- Add readL5Docs/readL2Docs store functions for project and impl docs - Create nodes/ and graphs/ directories on forge init - Inject docs into all design prompts (L3/L4/L5) when available - Add forge docs list/check CLI commands for coverage reporting - Enhance review prompt with docs-vs-implementation consistency check - Add MISSING_NODE_DOCS warning to forge check pipeline - Add i18n keys for docs-related messages (en/zh)
Add `forge prompt scan` command that generates AI prompts to reverse-engineer SVP artifacts from existing code, following L1 → L3 → L4 → L5 flow. - Phase 1: scan code → generate prompt to produce L3 contracts - Phase 2: use L3 → generate prompt to produce L4 flows - Phase 3: use L3+L4 → generate prompt to produce L5 blueprint - Auto-detects phase from .svp/ state - Supports --dir, --intent, --max-files options - Auto-excludes node_modules, dist, test files, .d.ts - Integrates Scan mode into slash command workflow (EN + ZH)
Changesets record a baseline snapshot of artifact revisions when work begins, then compute the diff at completion time. This follows SVP's "store less, compute more" principle. - `forge changeset start/complete/list/view/abandon` CLI commands - Changeset CRUD in store (writeChangeset, readChangeset, etc.) - computeBaselineFromArtifacts + computeDiff pure functions - Only one active changeset at a time - SCHEMA_VERSION bumped to 1.1.0 (no migration needed) - "changesets" added to .svp/ init subdirectories
…e materials Each L3 block can have an optional nodes/<block-id>/refs/ folder with arbitrary reference files. Text files are inlined into compile/recompile/review prompts; binary files (images, PDFs) are listed by path. - RefFile type + readNodeRefs/readGraphRefs in store - refs field added to ResolvedContext - ContextResolver loads refs alongside docs - formatRefs in prompt-builder injects into compile/recompile/review - Does NOT affect contentHash, NOT checked by forge docs
- Add [Alignment] Overview steps to Build workflow (L5/L4/L3) requiring user confirmation before proceeding to next layer (EN + ZH) - Add changeset start/complete hints to Add/Change workflows (EN + ZH) - Add refs/ documentation to slash command context sections (EN + ZH) - Add design quality guidelines to all prompt templates: - design-l5: domain boundary clarity, fine-grained domains - design-l4: avoid god blocks, split cross-cutting concerns - design-l3: single responsibility, pin count thresholds, multi-file OK - compile: one L3 can produce multiple files, 200-line split hint - Update README with OpenSpec complementary positioning (EN + ZH)
- Remove unused readFile/writeFile imports in manifest.test.ts - Wrap Date.now() in String() to satisfy restrict-template-expressions - Run prettier on all files to fix formatting
There was a problem hiding this comment.
Pull request overview
This PR is a major feature release that expands SVP/forge’s workflow and artifact model to better support brownfield projects, cross-artifact change tracking, and documentation/reference-material injection into prompts.
Changes:
- Added brownfield “scan” workflow (
forge prompt scan) with new scan prompt templates and a codebase scanner that extracts TS signatures into aScanContext. - Introduced schema manifest + migration framework (
.svp/manifest.json, migration registry/runner) and extended init structure (addschangesets/,nodes/,graphs/). - Added changeset system (
forge changeset start/complete/list/view/abandon) plus docs tooling (forge docs list/check) and prompt enhancements (docs/refs injection + design quality guidelines).
Reviewed changes
Copilot reviewed 43 out of 43 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| README.md | Updates positioning vs OpenSpec and clarifies complementary use. |
| i18n/zh/README.md | Chinese README parity updates for OpenSpec positioning. |
| packages/skills/prompts/scan.ts | Adds scan-phase prompt templates for reverse engineering L3/L4/L5. |
| packages/skills/prompts/review.ts | Extends review instructions to include docs comparison category. |
| packages/skills/prompts/design-l5.ts | Adds optional docs injection and design quality guidelines. |
| packages/skills/prompts/design-l4.ts | Adds optional docs injection and design quality guidelines. |
| packages/skills/prompts/design-l4-state-machine.ts | Adds optional docs injection. |
| packages/skills/prompts/design-l4-event-graph.ts | Adds optional docs injection. |
| packages/skills/prompts/design-l3.ts | Adds optional docs injection and design quality guidelines. |
| packages/skills/prompt-builder.ts | Injects refs into compile/recompile/review prompts and adds implementation quality guidelines. |
| packages/skills/index.ts | Re-exports scan prompt builders/types from the skills package. |
| packages/skills/adapters/shared.ts | Updates workflow docs (alignment-first, scan mode, changesets, refs) in protocol/workflow templates. |
| packages/skills/tests/scan-prompts.test.ts | Adds tests for scan prompt templates. |
| packages/skills/tests/prompt-builder.test.ts | Adds tests ensuring refs are injected into prompts correctly. |
| packages/core/store.ts | Adds refs reading, L5/L2 docs reading, and changeset CRUD + active lookup. |
| packages/core/store.test.ts | Adds tests for refs and new docs helpers. |
| packages/core/skill.ts | Extends resolved context to include refs. |
| packages/core/scan.ts | Adds codebase scanner producing ScanContext with exclusions and signature extraction. |
| packages/core/scan.test.ts | Adds tests for scan context collection behavior. |
| packages/core/migrations/index.ts | Adds migration registry scaffold. |
| packages/core/migrate.ts | Adds migration runner that chains major-version migrations. |
| packages/core/migrate.test.ts | Tests no-op and missing migration behavior. |
| packages/core/manifest.ts | Adds schema manifest handling + compatibility checks + migration hook. |
| packages/core/manifest.test.ts | Tests manifest read/write and compatibility behavior. |
| packages/core/init.ts | Extends init to create changesets dir + nodes/graphs dirs + writes manifest.json. |
| packages/core/index.ts | Exposes new APIs/types (refs, docs check, manifest/migrate, scan, changesets). |
| packages/core/i18n.ts | Adds i18n message for missing node docs warning. |
| packages/core/docs.ts | Adds pure docs coverage checker across L5/L4/L3. |
| packages/core/docs.test.ts | Tests docs checker behavior. |
| packages/core/check.ts | Adds optional doc-presence warnings for implemented (L2-mapped) L3 blocks. |
| packages/core/changeset.ts | Adds changeset model and diff/baseline computation helpers. |
| packages/core/changeset.test.ts | Adds tests for changeset baseline/diff/summary + store CRUD via core/store. |
| packages/cli/resolve.ts | Loads docs + refs into resolved prompt context for compile/recompile/review. |
| packages/cli/load.ts | Ensures schema compatibility before loading; scans existing node docs for warnings. |
| packages/cli/index.ts | Registers new CLI command groups (changeset, docs). |
| packages/cli/commands/view.ts | Ensures schema compatibility before rendering views. |
| packages/cli/commands/rehash.ts | Ensures schema compatibility before rehash operations. |
| packages/cli/commands/prompt.ts | Adds forge prompt scan and injects docs into design prompts. |
| packages/cli/commands/link.ts | Ensures schema compatibility before linking. |
| packages/cli/commands/init.ts | Updates init tree output to include nodes/graphs directories. |
| packages/cli/commands/docs.ts | Adds forge docs list and forge docs check. |
| packages/cli/commands/changeset.ts | Adds forge changeset subcommands. |
| packages/tests/e2e.test.ts | Updates E2E expectations to allow missing-node-docs warnings. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
Comment on lines
+62
to
+65
| } else if (currentRev > baseline[key]) { | ||
| modified.push({ layer, id, fromRev: baseline[key], toRev: currentRev }); | ||
| } else { | ||
| unchanged.push({ layer, id, rev: currentRev }); |
Comment on lines
+60
to
+107
| async function walkDir(dir: string, root: string): Promise<string[]> { | ||
| const result: string[] = []; | ||
|
|
||
| let entries: string[]; | ||
| try { | ||
| entries = await readdir(dir); | ||
| } catch { | ||
| return result; | ||
| } | ||
|
|
||
| for (const entry of entries) { | ||
| const fullPath = path.join(dir, entry); | ||
| let s; | ||
| try { | ||
| s = await stat(fullPath); | ||
| } catch { | ||
| continue; | ||
| } | ||
|
|
||
| if (s.isDirectory()) { | ||
| if (!shouldExcludeDir(entry)) { | ||
| const children = await walkDir(fullPath, root); | ||
| result.push(...children); | ||
| } | ||
| } else if (s.isFile() && !shouldExcludeFile(entry)) { | ||
| result.push(path.relative(root, fullPath)); | ||
| } | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| // ── Main collector ── | ||
|
|
||
| /** Collect scan context from an existing codebase for reverse generation prompts */ | ||
| export async function collectScanContext( | ||
| options: ScanOptions, | ||
| extractor?: SignatureExtractor, | ||
| ): Promise<ScanContext> { | ||
| const { root, dir, maxFiles } = options; | ||
| const scanDir = path.resolve(root, dir); | ||
|
|
||
| // Walk and collect all non-excluded files | ||
| const allFiles = await walkDir(scanDir, root); | ||
| allFiles.sort((a, b) => a.localeCompare(b)); | ||
|
|
||
| const truncated = allFiles.length > maxFiles; | ||
| const filesToProcess = allFiles.slice(0, maxFiles); |
| result.push(...children); | ||
| } | ||
| } else if (s.isFile() && !shouldExcludeFile(entry)) { | ||
| result.push(path.relative(root, fullPath)); |
Comment on lines
+171
to
+176
| const refs: RefFile[] = []; | ||
| for (const name of entries.toSorted()) { | ||
| const filePath = path.join(relDir, name); | ||
| const text = isTextFile(name); | ||
| const ref: RefFile = { name, path: filePath, isText: text }; | ||
| if (text) { |
Comment on lines
+218
to
+222
| /** 读取实现级文档 nodes/<blockRef>/impl.docs.md(部署注意事项、性能说明),不存在返回 null */ | ||
| export async function readL2Docs(root: string, l2Id: string): Promise<string | null> { | ||
| try { | ||
| return await readFile(path.join(root, "nodes", l2Id, "impl.docs.md"), "utf8"); | ||
| } catch { |
| let manifest = await readManifest(root); | ||
|
|
||
| if (manifest === null) { | ||
| // Legacy project without manifest — create one at v1.0.0 |
| .option("-r, --root <path>", "Project root directory", ".") | ||
| .action(async (options: { dir: string; intent?: string; maxFiles: string; root: string }) => { | ||
| const root = options.root; | ||
| const maxFiles = Number.parseInt(options.maxFiles, 10); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Major feature release introducing brownfield support, cross-artifact version tracking, reference materials, and alignment-first workflow.
New Features
forge prompt scan) — Generate AI prompts to reverse-engineer SVP artifacts from existing code, following L1 → L3 → L4 → L5 flow. Auto-detects phase from .svp/ state.forge changeset start/complete/list/view/abandon) — Cross-artifact version grouping. Records baseline snapshot, computes diff at completion. Only one active changeset at a time.refs/) — Optional per-block folder for design mockups, algorithm specs, reference implementations. Text files inlined into prompts, binary files listed by path.Infrastructure
manifest.json)changesets/added to .svp/ init structureStats
Test plan
npm test— 760 tests pass (29 test files)npm run check— tsc + eslint + prettier all clean