@cassiomc1/forgeloop 1.10.2 → 1.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/.cursor/rules/project-loop.mdc +2 -2
  2. package/.forgeloop/forgeloop.gitignore +1 -0
  3. package/.github/copilot-instructions.md +2 -2
  4. package/AGENTS.md +1 -0
  5. package/AGENT_COMPATIBILITY.md +7 -0
  6. package/CLAUDE.md +1 -0
  7. package/DOCS_INDEX.md +10 -0
  8. package/LOOP_SYSTEM_DESIGN.md +12 -0
  9. package/ORCHESTRATOR_INTEGRATION.md +9 -0
  10. package/PROTOCOL_INTEGRATION.md +17 -0
  11. package/README.md +12 -10
  12. package/THIRD_PARTY_NOTICES.md +11 -0
  13. package/THREAT_MODEL.md +21 -0
  14. package/benchmarks/repository-index/README.md +73 -0
  15. package/benchmarks/repository-index/queries.json +12 -0
  16. package/benchmarks/repository-index/run-hot-path.mjs +142 -0
  17. package/benchmarks/repository-index/run-persistent-transport.mjs +169 -0
  18. package/completions/_forgeloop +7 -1
  19. package/completions/forgeloop.bash +13 -1
  20. package/completions/forgeloop.fish +40 -1
  21. package/docs/AGENT_PROTOCOL_SUMMARY.md +8 -1
  22. package/docs/CLI_REFERENCE.md +114 -2
  23. package/docs/DOCUMENTATION_GUIDE.md +10 -5
  24. package/docs/GETTING_STARTED.md +17 -0
  25. package/docs/MCP.md +16 -1
  26. package/docs/PACKAGE_CONTENTS.md +7 -1
  27. package/docs/PERSISTENT_SEARCH_TRANSPORT.md +289 -0
  28. package/docs/RECIPES.md +30 -0
  29. package/docs/RELEASE_CHECKLIST.md +34 -0
  30. package/docs/REPOSITORY_INDEX.md +553 -0
  31. package/docs/TROUBLESHOOTING.md +147 -0
  32. package/docs/UNIVERSAL_INTEGRATION.md +30 -0
  33. package/docs/diagrams/README.md +10 -0
  34. package/package.json +11 -2
  35. package/scripts/update-tgrep-manifest.mjs +86 -0
  36. package/scripts/verify-tgrep-manifest.mjs +17 -0
  37. package/src/cli.js +35 -0
  38. package/src/commands/doctor.js +76 -1
  39. package/src/commands/index-rebuild.js +1 -0
  40. package/src/commands/index-setup.js +1 -0
  41. package/src/commands/index-start.js +1 -0
  42. package/src/commands/index-status.js +1 -0
  43. package/src/commands/index-stop.js +1 -0
  44. package/src/commands/init.js +39 -1
  45. package/src/commands/repository-index.js +111 -0
  46. package/src/commands/search.js +1 -0
  47. package/src/commands/update.js +32 -4
  48. package/src/core/cli-command-definitions.js +97 -3
  49. package/src/core/command-executors.js +35 -2
  50. package/src/core/command-input.js +23 -0
  51. package/src/core/error-codes.js +195 -0
  52. package/src/core/filesystem.js +10 -1
  53. package/src/core/integration-invocation-policy.js +27 -0
  54. package/src/core/integration-resources.js +16 -1
  55. package/src/core/protocol-info.js +23 -0
  56. package/src/integration.d.ts +90 -0
  57. package/src/integration.js +21 -0
  58. package/src/persistent-transport/client.js +293 -0
  59. package/src/persistent-transport/constants.js +24 -0
  60. package/src/persistent-transport/errors.js +38 -0
  61. package/src/persistent-transport/framing.js +61 -0
  62. package/src/persistent-transport/lifecycle.js +116 -0
  63. package/src/persistent-transport/ownership.js +184 -0
  64. package/src/persistent-transport/paths.js +31 -0
  65. package/src/persistent-transport/protocol.js +95 -0
  66. package/src/persistent-transport/server.js +256 -0
  67. package/src/persistent-transport/state.js +49 -0
  68. package/src/repository-index/args.js +59 -0
  69. package/src/repository-index/binary-manager.js +413 -0
  70. package/src/repository-index/constants.js +45 -0
  71. package/src/repository-index/errors.js +38 -0
  72. package/src/repository-index/lifecycle.js +17 -0
  73. package/src/repository-index/lock.js +113 -0
  74. package/src/repository-index/manifest.js +132 -0
  75. package/src/repository-index/metrics.js +30 -0
  76. package/src/repository-index/normalize-json.js +187 -0
  77. package/src/repository-index/paths.js +39 -0
  78. package/src/repository-index/platform.js +20 -0
  79. package/src/repository-index/process.js +140 -0
  80. package/src/repository-index/readiness.js +62 -0
  81. package/src/repository-index/search.js +262 -0
  82. package/src/repository-index/server.js +432 -0
  83. package/src/repository-index/status.js +397 -0
  84. package/src/repository-index/tgrep-manifest.json +38 -0
@@ -0,0 +1,169 @@
1
+ import { appendFile, cp, mkdtemp, readFile, rm } from "node:fs/promises";
2
+ import { execFile } from "node:child_process";
3
+ import { performance } from "node:perf_hooks";
4
+ import { promisify } from "node:util";
5
+ import os from "node:os";
6
+ import path from "node:path";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ import { searchRepository } from "../../src/repository-index/search.js";
10
+ import { createTgrepBinaryHandle, runTgrep } from "../../src/repository-index/process.js";
11
+ import { stopRepositoryIndexServer } from "../../src/repository-index/server.js";
12
+ import { getCanonicalRepositorySearchArgs, appendSearchFilters } from "../../src/repository-index/args.js";
13
+ import { getTgrepIndexPath } from "../../src/repository-index/paths.js";
14
+ import { searchViaPersistentTransport, shutdownPersistentSearchHost } from "../../src/persistent-transport/client.js";
15
+
16
+ const execFileAsync = promisify(execFile);
17
+ const packageRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../..");
18
+ const fixtureRoot = path.join(packageRoot, "tests", "fixtures", "repository-index", "sample-repo");
19
+ const cliPath = path.join(packageRoot, "src", "cli.js");
20
+ const binary = process.env.FORGELOOP_TGREP_BINARY;
21
+ const iterations = Number.parseInt(process.env.FORGELOOP_BENCHMARK_ITERATIONS ?? "100", 10);
22
+
23
+ if (!binary || !path.isAbsolute(binary)) throw new Error("Set FORGELOOP_TGREP_BINARY to the absolute path of the pinned native tgrep binary");
24
+ if (!Number.isSafeInteger(iterations) || iterations < 1 || iterations > 1_000) throw new Error("FORGELOOP_BENCHMARK_ITERATIONS must be an integer from 1 to 1000");
25
+ const binaryHandle = createTgrepBinaryHandle(binary);
26
+
27
+ const fixture = await mkdtemp(path.join(os.tmpdir(), "forgeloop-persistent-transport-benchmark-"));
28
+ const persistentHome = await mkdtemp(path.join(os.tmpdir(), "forgeloop-persistent-transport-home-"));
29
+ const cliHome = await mkdtemp(path.join(os.tmpdir(), "forgeloop-persistent-transport-cli-home-"));
30
+ const options = {
31
+ packageRoot,
32
+ binaryPath: binary,
33
+ startupTimeoutMs: 30_000,
34
+ commandTimeoutMs: 60_000,
35
+ requestTimeoutMs: 60_000,
36
+ };
37
+ const query = { pattern: "FORGELOOP_BENCHMARK_ABSENT", fixedStrings: true };
38
+ const agentQueries = [
39
+ { pattern: "repositoryFingerprint", fixedStrings: true },
40
+ { pattern: "E_[A-Z_]+" },
41
+ { pattern: "executionreceipt", ignoreCase: true },
42
+ { pattern: "receipt", wordRegexp: true },
43
+ { pattern: "export", types: ["js"] },
44
+ { pattern: "const", fixedStrings: true },
45
+ { pattern: "FORGELOOP_BENCHMARK_ABSENT", fixedStrings: true },
46
+ { pattern: "searchRepository", fixedStrings: true },
47
+ { pattern: "forgeloop", ignoreCase: true },
48
+ { pattern: "THREAT_MODEL", fixedStrings: true },
49
+ ];
50
+
51
+ function summarize(durations) {
52
+ const sorted = [...durations].sort((a, b) => a - b);
53
+ const percentile = (fraction) => sorted[Math.min(sorted.length - 1, Math.ceil(sorted.length * fraction) - 1)];
54
+ const totalMs = durations.reduce((sum, value) => sum + value, 0);
55
+ return {
56
+ iterations: durations.length,
57
+ totalMs: Math.round(totalMs),
58
+ minMs: Math.round(sorted[0]),
59
+ maxMs: Math.round(sorted.at(-1)),
60
+ meanMs: Math.round(totalMs / durations.length),
61
+ medianMs: Math.round(percentile(0.5)),
62
+ p95Ms: Math.round(percentile(0.95)),
63
+ };
64
+ }
65
+
66
+ async function repeated(callback) {
67
+ const durations = [];
68
+ for (let index = 0; index < iterations; index += 1) {
69
+ const startedAt = performance.now();
70
+ await callback();
71
+ durations.push(performance.now() - startedAt);
72
+ }
73
+ return summarize(durations);
74
+ }
75
+
76
+ async function rawTgrep(searchQuery = query) {
77
+ const args = [...getCanonicalRepositorySearchArgs({ indexPath: getTgrepIndexPath(fixture), pattern: searchQuery.pattern, options: searchQuery })];
78
+ appendSearchFilters(args, searchQuery);
79
+ args.push(fixture);
80
+ const result = await runTgrep({ binary: binaryHandle, repoRoot: fixture, args, timeoutMs: options.commandTimeoutMs, maxOutputBytes: 4 * 1024 * 1024 });
81
+ if (![0, 1].includes(result.exitCode)) throw new Error(`raw tgrep failed: ${result.stderr}`);
82
+ }
83
+
84
+ async function ripgrep(searchQuery = query) {
85
+ try {
86
+ await execFileAsync("rg", ["--fixed-strings", "--color", "never", "--glob", "!.forgeloop/repository-index/**", searchQuery.pattern, fixture], { maxBuffer: 4 * 1024 * 1024 });
87
+ } catch (error) {
88
+ if (error.code === "ENOENT") return false;
89
+ if (error.code !== 1) throw error;
90
+ }
91
+ return true;
92
+ }
93
+
94
+ async function cliSearch(homeDirectory, searchQuery = query) {
95
+ const fixed = searchQuery.fixedStrings ? ["--fixed-strings"] : [];
96
+ const ignoreCase = searchQuery.ignoreCase ? ["--ignore-case"] : [];
97
+ const word = searchQuery.wordRegexp ? ["--word-regexp"] : [];
98
+ const type = searchQuery.types?.flatMap((value) => ["--type", value]) ?? [];
99
+ const result = await execFileAsync(process.execPath, [cliPath, "search", searchQuery.pattern, ...fixed, ...ignoreCase, ...word, ...type, "--json", "--path", fixture], {
100
+ cwd: packageRoot,
101
+ env: { ...process.env, HOME: homeDirectory, USERPROFILE: homeDirectory, FORGELOOP_TGREP_BINARY: binary },
102
+ timeout: 120_000,
103
+ maxBuffer: 16 * 1024 * 1024,
104
+ });
105
+ return JSON.parse(result.stdout);
106
+ }
107
+
108
+ async function measureAgentWorkload(callback) {
109
+ const startedAt = performance.now();
110
+ const results = [];
111
+ for (const searchQuery of agentQueries) results.push(await callback(searchQuery));
112
+ const totalMs = performance.now() - startedAt;
113
+ return {
114
+ queries: agentQueries.length,
115
+ totalMs: Math.round(totalMs),
116
+ meanMs: Math.round(totalMs / agentQueries.length),
117
+ matchCounts: results.map((result) => result?.matches?.length ?? null),
118
+ };
119
+ }
120
+
121
+ try {
122
+ await cp(fixtureRoot, fixture, { recursive: true });
123
+ await execFileAsync("git", ["init", "--quiet", fixture]);
124
+ await execFileAsync("git", ["-C", fixture, "add", "."]);
125
+ await searchRepository(fixture, { ...options, ...query, homeDirectory: persistentHome });
126
+ const persistentColdStartedAt = performance.now();
127
+ await searchViaPersistentTransport(fixture, query, { ...options, homeDirectory: persistentHome, env: { FORGELOOP_TGREP_BINARY: binary } });
128
+ const persistentColdMs = performance.now() - persistentColdStartedAt;
129
+ const persistentWarm = await repeated(() => searchViaPersistentTransport(fixture, query, { ...options, homeDirectory: persistentHome, env: { FORGELOOP_TGREP_BINARY: binary } }));
130
+ const apiWarm = await repeated(() => searchRepository(fixture, { ...options, ...query, homeDirectory: persistentHome }));
131
+ const raw = await repeated(rawTgrep);
132
+ const rgAvailable = await ripgrep();
133
+ const rgWarm = rgAvailable ? await repeated(ripgrep) : null;
134
+ const cliColdStartedAt = performance.now();
135
+ await cliSearch(cliHome);
136
+ const cliColdMs = performance.now() - cliColdStartedAt;
137
+ const cliWarm = await repeated(() => cliSearch(cliHome));
138
+ const agentWorkload = {
139
+ api: await measureAgentWorkload((searchQuery) => searchRepository(fixture, { ...options, ...searchQuery, homeDirectory: persistentHome })),
140
+ persistentTransport: await measureAgentWorkload((searchQuery) => searchViaPersistentTransport(fixture, searchQuery, { ...options, homeDirectory: persistentHome, env: { FORGELOOP_TGREP_BINARY: binary } })),
141
+ cli: await measureAgentWorkload((searchQuery) => cliSearch(cliHome, searchQuery)),
142
+ };
143
+ const nodeStartupStartedAt = performance.now();
144
+ await execFileAsync(process.execPath, ["-e", "void 0"], { cwd: packageRoot });
145
+ const nodeStartupMs = performance.now() - nodeStartupStartedAt;
146
+ await appendFile(path.join(fixture, "src", "benchmark.js"), "\nexport const transportBenchmarkMutation = true;\n");
147
+ await searchViaPersistentTransport(fixture, { pattern: "transportBenchmarkMutation", fixedStrings: true }, { ...options, homeDirectory: persistentHome, env: { FORGELOOP_TGREP_BINARY: binary } });
148
+ console.log(JSON.stringify({
149
+ schemaVersion: 1,
150
+ repository: "repository-index-sample-fixture",
151
+ platform: process.platform,
152
+ arch: process.arch,
153
+ nodeVersion: process.version,
154
+ tgrepVersion: "1.0.3",
155
+ iterations,
156
+ cold: { persistentTransportMs: Math.round(persistentColdMs), cliMs: Math.round(cliColdMs) },
157
+ warm: { api: apiWarm, persistentTransport: persistentWarm, cli: cliWarm, rawTgrep: raw, ripgrep: rgWarm },
158
+ agentWorkload,
159
+ criticalPath: { nodeProcessStartupMs: Math.round(nodeStartupMs), note: "CLI timings include Node process startup and argument parsing." },
160
+ mutation: "verified through persistent transport",
161
+ }, null, 2));
162
+ } finally {
163
+ await shutdownPersistentSearchHost({ homeDirectory: persistentHome, timeoutMs: 2_000 }).catch(() => {});
164
+ await shutdownPersistentSearchHost({ homeDirectory: cliHome, timeoutMs: 2_000 }).catch(() => {});
165
+ await stopRepositoryIndexServer(fixture, { ...options, homeDirectory: persistentHome }).catch(() => {});
166
+ await rm(fixture, { recursive: true, force: true });
167
+ await rm(persistentHome, { recursive: true, force: true });
168
+ await rm(cliHome, { recursive: true, force: true });
169
+ }
@@ -1,7 +1,7 @@
1
1
  #compdef forgeloop
2
2
  # Generated by scripts/generate-shell-completions.mjs. Do not edit.
3
3
  _arguments \
4
- '1:command:(action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status)' \
4
+ '1:command:(action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check search status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status)' \
5
5
  '*::options:->options'
6
6
  case $words[2] in
7
7
  action-authorize) _arguments '--action[durable action ID]' '--approval[current fingerprint-bound approval]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
@@ -33,6 +33,11 @@ case $words[2] in
33
33
  handoff-list) _arguments '--help[show this help]' '--json[emit handoff list as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
34
34
  handoff-show) _arguments '--help[show this help]' '--id[handoff identifier]' '--json[emit handoff as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
35
35
  history) _arguments '--checks[show only verification events]' '--compact[one line per event]' '--failures[show only failed/blocked verification events]' '--help[show this help]' '--json[emit structured history output as JSON]' '--limit[show only the last N events after filtering]' '--path[target project directory (default: current directory)]' '--phase[comma-separated lifecycle phases to include]' '--since[include events at or after this timestamp]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--type[comma-separated event types or categories to include]' '--until[include events at or before this timestamp]' '--verbose[show full event data]' '--version[show the installed package version]' ;;
36
+ index-rebuild) _arguments '--asset[use a preloaded pinned tgrep archive instead of downloading]' '--help[show this help]' '--json[emit repository-index rebuild as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
37
+ index-setup) _arguments '--asset[use a preloaded pinned tgrep archive instead of downloading]' '--force[rebuild the repository index even when metadata is current]' '--help[show this help]' '--json[emit repository-index setup as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
38
+ index-start) _arguments '--help[show this help]' '--json[emit repository-index start as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
39
+ index-status) _arguments '--help[show this help]' '--json[emit repository-index health as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
40
+ index-stop) _arguments '--help[show this help]' '--json[emit repository-index stop as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
36
41
  init) _arguments '--dry-run[perform deterministic init planning and conflict detection without writing]' '--help[show this help]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
37
42
  inspect) _arguments '--contract-file[current JSON contract used for freshness comparison]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
38
43
  metrics) _arguments '--help[show this help]' '--json[emit trajectory metrics as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
@@ -67,6 +72,7 @@ case $words[2] in
67
72
  rule-verify) _arguments '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--rule[verify a specific policy rule ID]' '--version[show the installed package version]' ;;
68
73
  run-action) _arguments '--[exact command argv; shell mode is never used]' '--action[stable durable action ID]' '--approval[current fingerprint-bound approval]' '--capability[canonical action capability]' '--effect-class[durable action effect class]' '--help[show this help]' '--idempotency-key[immutable logical action idempotency key]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--required-for-completion[mark the action as required for completion]' '--requirement[bound completion requirement]' '--target[bounded external action target]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--timeout-ms[maximum command duration before termination]' '--version[show the installed package version]' ;;
69
74
  run-check) _arguments '--[exact command argv to classify, execute, and attest]' '--details[additional structured check details]' '--help[show this help]' '--id[stable check identifier]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--requirement[completion requirement covered by the check]' '--scope-ref[current verification-scope.json to bind to execution evidence]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--timeout-ms[maximum command duration before termination]' '--version[show the installed package version]' ;;
75
+ search) _arguments '--after-context[lines of context after matches]' '--before-context[lines of context before matches]' '--context[lines of context before and after matches]' '--files-with-matches[return matching file paths only]' '--fixed-strings[treat the pattern as a literal string]' '--glob[include files matching a glob]' '--help[show this help]' '--ignore-case[search case-insensitively]' '--json[emit normalized provider-neutral search JSON]' '--max-count[maximum matches per file]' '--path[target project directory (default: current directory)]' '--smart-case[use case-insensitive search only for lowercase patterns]' '--stats[include observed native search statistics]' '--type[include files of a tgrep type]' '--version[show the installed package version]' '--word-regexp[match whole words only]' ;;
70
76
  status) _arguments '--contract-file[current JSON contract used for freshness comparison]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
71
77
  task-create) _arguments '--claim[scoped file path or directory prefix claimed for mutation]' '--contract-file[path to initial contract file]' '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--task[task ID to operate on (when omitted, resolved from context or single active task)]' '--version[show the installed package version]' ;;
72
78
  task-list) _arguments '--help[show this help]' '--json[emit structured output as JSON]' '--path[target project directory (default: current directory)]' '--version[show the installed package version]' ;;
@@ -35,6 +35,11 @@ _forgeloop() {
35
35
  handoff-list) command="handoff-list" ;;
36
36
  handoff-show) command="handoff-show" ;;
37
37
  history) command="history" ;;
38
+ index-rebuild) command="index-rebuild" ;;
39
+ index-setup) command="index-setup" ;;
40
+ index-start) command="index-start" ;;
41
+ index-status) command="index-status" ;;
42
+ index-stop) command="index-stop" ;;
38
43
  init) command="init" ;;
39
44
  inspect) command="inspect" ;;
40
45
  metrics) command="metrics" ;;
@@ -69,6 +74,7 @@ _forgeloop() {
69
74
  rule-verify) command="rule-verify" ;;
70
75
  run-action) command="run-action" ;;
71
76
  run-check) command="run-check" ;;
77
+ search) command="search" ;;
72
78
  status) command="status" ;;
73
79
  task-create) command="task-create" ;;
74
80
  task-list) command="task-list" ;;
@@ -92,7 +98,7 @@ _forgeloop() {
92
98
  esac
93
99
  done
94
100
  if [[ -z "\${command}" && "\${cur}" != -* ]]; then
95
- COMPREPLY=( $(compgen -W 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status' -- "$cur") )
101
+ COMPREPLY=( $(compgen -W 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check search status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status' -- "$cur") )
96
102
  return
97
103
  fi
98
104
  case "\${command}" in
@@ -125,6 +131,11 @@ _forgeloop() {
125
131
  handoff-list) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
126
132
  handoff-show) COMPREPLY=( $(compgen -W '--help --id --json --path --task --version' -- "$cur") );;
127
133
  history) COMPREPLY=( $(compgen -W '--checks --compact --failures --help --json --limit --path --phase --since --task --type --until --verbose --version' -- "$cur") );;
134
+ index-rebuild) COMPREPLY=( $(compgen -W '--asset --help --json --path --version' -- "$cur") );;
135
+ index-setup) COMPREPLY=( $(compgen -W '--asset --force --help --json --path --version' -- "$cur") );;
136
+ index-start) COMPREPLY=( $(compgen -W '--help --json --path --version' -- "$cur") );;
137
+ index-status) COMPREPLY=( $(compgen -W '--help --json --path --version' -- "$cur") );;
138
+ index-stop) COMPREPLY=( $(compgen -W '--help --json --path --version' -- "$cur") );;
128
139
  init) COMPREPLY=( $(compgen -W '--dry-run --help --path --version' -- "$cur") );;
129
140
  inspect) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --task --version' -- "$cur") );;
130
141
  metrics) COMPREPLY=( $(compgen -W '--help --json --path --task --version' -- "$cur") );;
@@ -159,6 +170,7 @@ _forgeloop() {
159
170
  rule-verify) COMPREPLY=( $(compgen -W '--help --json --path --rule --version' -- "$cur") );;
160
171
  run-action) COMPREPLY=( $(compgen -W '-- --action --approval --capability --effect-class --help --idempotency-key --json --path --required-for-completion --requirement --target --task --timeout-ms --version' -- "$cur") );;
161
172
  run-check) COMPREPLY=( $(compgen -W '-- --details --help --id --json --path --requirement --scope-ref --task --timeout-ms --version' -- "$cur") );;
173
+ search) COMPREPLY=( $(compgen -W '--after-context --before-context --context --files-with-matches --fixed-strings --glob --help --ignore-case --json --max-count --path --smart-case --stats --type --version --word-regexp' -- "$cur") );;
162
174
  status) COMPREPLY=( $(compgen -W '--contract-file --help --json --path --task --version' -- "$cur") );;
163
175
  task-create) COMPREPLY=( $(compgen -W '--claim --contract-file --help --json --path --task --version' -- "$cur") );;
164
176
  task-list) COMPREPLY=( $(compgen -W '--help --json --path --version' -- "$cur") );;
@@ -1,5 +1,5 @@
1
1
  # Generated by scripts/generate-shell-completions.mjs. Do not edit.
2
- complete -c forgeloop -f -n '__fish_use_subcommand' -a 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status'
2
+ complete -c forgeloop -f -n '__fish_use_subcommand' -a 'action-authorize action-propose action-reconcile action-record action-show action-verify activate advance approval-request approval-resolve attestation-create attestation-status attestation-verify attestation-verify-range audit baseline bundle clear-continuity clear-state complete continuity doctor efficiency eval handoff-accept handoff-create handoff-list handoff-show history index-rebuild index-setup index-start index-status index-stop init inspect metrics migrate-protocol next policy policy-diff policy-discover policy-status preflight prepare-completion profile-interview progress protocol-info quality-baseline quality-status quality-verify reconcile-closure reconcile-continuity record-check record-continuity record-decision-criterion record-diagnosis record-hypothesis-disposition record-intervention record-terminal-result reflect report responsibility-set responsibility-status route rule-verify run-action run-check search status task-create task-list task-lock-status task-migrate task-recover task-repair-legacy-recovery task-resume task-scope task-show task-unlock trace update usage-record validate-protocol validate-receipt validate-state verify-scope workspace-bind workspace-status'
3
3
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'action' -d 'durable action ID'
4
4
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'approval' -d 'current fingerprint-bound approval'
5
5
  complete -c forgeloop -f -n '__fish_seen_subcommand_from action-authorize' -l 'help' -d 'show this help'
@@ -213,6 +213,29 @@ complete -c forgeloop -f -n '__fish_seen_subcommand_from history' -l 'type' -d '
213
213
  complete -c forgeloop -f -n '__fish_seen_subcommand_from history' -l 'until' -d 'include events at or before this timestamp'
214
214
  complete -c forgeloop -f -n '__fish_seen_subcommand_from history' -l 'verbose' -d 'show full event data'
215
215
  complete -c forgeloop -f -n '__fish_seen_subcommand_from history' -l 'version' -d 'show the installed package version'
216
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-rebuild' -l 'asset' -d 'use a preloaded pinned tgrep archive instead of downloading'
217
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-rebuild' -l 'help' -d 'show this help'
218
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-rebuild' -l 'json' -d 'emit repository-index rebuild as JSON'
219
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-rebuild' -l 'path' -d 'target project directory (default: current directory)'
220
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-rebuild' -l 'version' -d 'show the installed package version'
221
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'asset' -d 'use a preloaded pinned tgrep archive instead of downloading'
222
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'force' -d 'rebuild the repository index even when metadata is current'
223
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'help' -d 'show this help'
224
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'json' -d 'emit repository-index setup as JSON'
225
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'path' -d 'target project directory (default: current directory)'
226
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-setup' -l 'version' -d 'show the installed package version'
227
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-start' -l 'help' -d 'show this help'
228
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-start' -l 'json' -d 'emit repository-index start as JSON'
229
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-start' -l 'path' -d 'target project directory (default: current directory)'
230
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-start' -l 'version' -d 'show the installed package version'
231
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-status' -l 'help' -d 'show this help'
232
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-status' -l 'json' -d 'emit repository-index health as JSON'
233
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-status' -l 'path' -d 'target project directory (default: current directory)'
234
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-status' -l 'version' -d 'show the installed package version'
235
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-stop' -l 'help' -d 'show this help'
236
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-stop' -l 'json' -d 'emit repository-index stop as JSON'
237
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-stop' -l 'path' -d 'target project directory (default: current directory)'
238
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from index-stop' -l 'version' -d 'show the installed package version'
216
239
  complete -c forgeloop -f -n '__fish_seen_subcommand_from init' -l 'dry-run' -d 'perform deterministic init planning and conflict detection without writing'
217
240
  complete -c forgeloop -f -n '__fish_seen_subcommand_from init' -l 'help' -d 'show this help'
218
241
  complete -c forgeloop -f -n '__fish_seen_subcommand_from init' -l 'path' -d 'target project directory (default: current directory)'
@@ -462,6 +485,22 @@ complete -c forgeloop -f -n '__fish_seen_subcommand_from run-check' -l 'scope-re
462
485
  complete -c forgeloop -f -n '__fish_seen_subcommand_from run-check' -l 'task' -d 'task ID to operate on (when omitted, resolved from context or single active task)'
463
486
  complete -c forgeloop -f -n '__fish_seen_subcommand_from run-check' -l 'timeout-ms' -d 'maximum command duration before termination'
464
487
  complete -c forgeloop -f -n '__fish_seen_subcommand_from run-check' -l 'version' -d 'show the installed package version'
488
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'after-context' -d 'lines of context after matches'
489
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'before-context' -d 'lines of context before matches'
490
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'context' -d 'lines of context before and after matches'
491
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'files-with-matches' -d 'return matching file paths only'
492
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'fixed-strings' -d 'treat the pattern as a literal string'
493
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'glob' -d 'include files matching a glob'
494
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'help' -d 'show this help'
495
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'ignore-case' -d 'search case-insensitively'
496
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'json' -d 'emit normalized provider-neutral search JSON'
497
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'max-count' -d 'maximum matches per file'
498
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'path' -d 'target project directory (default: current directory)'
499
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'smart-case' -d 'use case-insensitive search only for lowercase patterns'
500
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'stats' -d 'include observed native search statistics'
501
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'type' -d 'include files of a tgrep type'
502
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'version' -d 'show the installed package version'
503
+ complete -c forgeloop -f -n '__fish_seen_subcommand_from search' -l 'word-regexp' -d 'match whole words only'
465
504
  complete -c forgeloop -f -n '__fish_seen_subcommand_from status' -l 'contract-file' -d 'current JSON contract used for freshness comparison'
466
505
  complete -c forgeloop -f -n '__fish_seen_subcommand_from status' -l 'help' -d 'show this help'
467
506
  complete -c forgeloop -f -n '__fish_seen_subcommand_from status' -l 'json' -d 'emit structured output as JSON'
@@ -7,7 +7,7 @@
7
7
  ForgeLoop is a portable protocol and support CLI for verifiable engineering workflows. It records and validates task state, contracts, routing, checks, evidence, continuity, and optional code attestations. It does not become an agent scheduler, delegation service, source-control authority, or secret manager.
8
8
 
9
9
  Protocol version: 1
10
- Package version: 1.10.2
10
+ Package version: 1.11.0
11
11
 
12
12
  ## Canonical loop
13
13
 
@@ -90,6 +90,7 @@ Phases: RECEIVED, DISCOVERING, CONTRACT_READY, ROUTED, DESIGNING, PLANNED, EXECU
90
90
  | integrationApi | 1 | yes |
91
91
  | observabilityStability | n/a | yes |
92
92
  | reflection | 1 | yes |
93
+ | repositoryIndex | 1 | yes |
93
94
  | responsibilityConstraints | 1 | yes |
94
95
  | structuralQuality | 1 | yes |
95
96
  | structuredTrace | 1 | yes |
@@ -198,12 +199,14 @@ capability-family versions.
198
199
  | efficiency | READ_ONLY | Projects usage and timing efficiency, comparing only against a metadata-compatible local baseline. |
199
200
  | eval | MUTATING | Evaluates the current trajectory against a validated project-local reference scenario. |
200
201
  | history | READ_ONLY | Shows chronological protocol history reconstructed from canonical ForgeLoop state. |
202
+ | index-status | READ_ONLY | Reports provider-neutral repository-index health, metadata, and owned-server status. |
201
203
  | inspect | READ_ONLY | Inspects target repository health, dirty files, active branch, and artifact freshness. |
202
204
  | metrics | READ_ONLY | Projects trajectory, action, execution, timing, and known usage metrics without mutating state. |
203
205
  | profile-interview | READ_ONLY | Optional interactive or dry-run interview to refine project profile facts. |
204
206
  | progress | READ_ONLY | Evaluates task progress across verification cycles and detects stalls deterministically. |
205
207
  | protocol-info | READ_ONLY | Reports versioning, lifecycle, command, guide, and public error compatibility metadata for external harnesses. |
206
208
  | reflect | READ_ONLY | Analyzes diagnostic and correction history deterministically for information gain, repeated failures, ineffective interventions, and oscillation. |
209
+ | search | READ_ONLY | Searches the ForgeLoop repository index through the provider-neutral search contract. |
207
210
  | status | READ_ONLY | Displays current lifecycle phase, active checks, blockers, and artifact freshness bindings. |
208
211
  | trace | READ_ONLY | Emits detailed structured task trace with provenance and artifact relationships. |
209
212
  | usage-record | MUTATING | Records actor-reported usage telemetry without treating it as verification evidence. |
@@ -248,6 +251,10 @@ capability-family versions.
248
251
 
249
252
  | Command | Mutation | Purpose |
250
253
  | --- | --- | --- |
254
+ | index-rebuild | MUTATING | Atomically rebuilds the repository index and restarts its owned watcher. |
255
+ | index-setup | MUTATING | Provisions the pinned tgrep engine, builds the repository index, and starts its owned watcher. |
256
+ | index-start | MUTATING | Starts the owned tgrep repository-index watcher after an index has been built. |
257
+ | index-stop | MUTATING | Stops only a tgrep server whose process identity is provably owned by ForgeLoop. |
251
258
  | init | MUTATING | Initializes a target project directory with ForgeLoop discovery adapters, schemas, and templates. |
252
259
  | migrate-protocol | MUTATING | Safely migrates explicitly supported protocol state; unknown target versions fail without rewriting artifacts. |
253
260
  | task-migrate | MUTATING | Migrates a legacy 1.0 singleton task state layout into a task-namespaced layout. |
@@ -58,8 +58,8 @@ error codes. Default output and default JSON remain unchanged.
58
58
 
59
59
  | Category | Commands |
60
60
  | --- | --- |
61
- | **Inspection & Diagnostics** | [`protocol-info`](#protocol-info), [`doctor`](#doctor), [`metrics`](#metrics), [`usage-record`](#usage-record), [`efficiency`](#efficiency), [`eval`](#eval), [`history`](#history), [`trace`](#trace), [`reflect`](#reflect), [`progress`](#progress), [`profile-interview`](#profile-interview), [`inspect`](#inspect), [`status`](#status), [`validate-state`](#validate-state), [`validate-protocol`](#validate-protocol) |
62
- | **Setup & Maintenance** | [`init`](#init), [`update`](#update), [`task-migrate`](#task-migrate), [`migrate-protocol`](#migrate-protocol), [`task-unlock`](#task-unlock), [`task-recover`](#task-recover), [`task-repair-legacy-recovery`](#task-repair-legacy-recovery), [`task-resume`](#task-resume) |
61
+ | **Inspection & Diagnostics** | [`protocol-info`](#protocol-info), [`doctor`](#doctor), [`index-status`](#index-status), [`search`](#search), [`metrics`](#metrics), [`usage-record`](#usage-record), [`efficiency`](#efficiency), [`eval`](#eval), [`history`](#history), [`trace`](#trace), [`reflect`](#reflect), [`progress`](#progress), [`profile-interview`](#profile-interview), [`inspect`](#inspect), [`status`](#status), [`validate-state`](#validate-state), [`validate-protocol`](#validate-protocol) |
62
+ | **Setup & Maintenance** | [`init`](#init), [`index-setup`](#index-setup), [`index-start`](#index-start), [`index-stop`](#index-stop), [`index-rebuild`](#index-rebuild), [`update`](#update), [`task-migrate`](#task-migrate), [`migrate-protocol`](#migrate-protocol), [`task-unlock`](#task-unlock), [`task-recover`](#task-recover), [`task-repair-legacy-recovery`](#task-repair-legacy-recovery), [`task-resume`](#task-resume) |
63
63
  | **Lifecycle & State** | [`activate`](#activate), [`route`](#route), [`preflight`](#preflight), [`advance`](#advance), [`next`](#next), [`record-diagnosis`](#record-diagnosis), [`record-intervention`](#record-intervention), [`record-hypothesis-disposition`](#record-hypothesis-disposition), [`record-decision-criterion`](#record-decision-criterion), [`complete`](#complete), [`clear-state`](#clear-state), [`reconcile-closure`](#reconcile-closure), [`task-create`](#task-create), [`task-list`](#task-list), [`task-show`](#task-show), [`task-lock-status`](#task-lock-status), [`task-scope`](#task-scope) |
64
64
  | **Verification & Completion** | [`quality-baseline`](#quality-baseline), [`quality-verify`](#quality-verify), [`quality-status`](#quality-status), [`prepare-completion`](#prepare-completion), [`run-check`](#run-check), [`record-check`](#record-check), [`record-terminal-result`](#record-terminal-result), [`audit`](#audit), [`report`](#report), [`validate-receipt`](#validate-receipt), [`verify-scope`](#verify-scope) |
65
65
  | **Cross-Harness Continuity** | [`continuity`](#continuity), [`record-continuity`](#record-continuity), [`reconcile-continuity`](#reconcile-continuity), [`clear-continuity`](#clear-continuity), [`handoff-create`](#handoff-create), [`handoff-list`](#handoff-list), [`handoff-show`](#handoff-show) |
@@ -76,6 +76,118 @@ error codes. Default output and default JSON remain unchanged.
76
76
 
77
77
  ## 1. Setup & Maintenance
78
78
 
79
+ ### `index-setup`
80
+
81
+ Provisions or reuses the managed Repository Index engine, builds its derived
82
+ index, and starts the owned watcher.
83
+
84
+ - **Purpose**: Establish mandatory repository-search readiness.
85
+ - **Mutation**: Writes only Repository Index runtime state and cache data.
86
+ - **Options**:
87
+
88
+ <!-- BEGIN FORGELOOP GENERATED: cli:index-setup:options -->
89
+
90
+ - `--path <directory>`: target project directory (default: current directory)
91
+ - `--asset <path>`: use a preloaded pinned tgrep archive instead of downloading
92
+ - `--force`: rebuild the repository index even when metadata is current
93
+ - `--json`: emit repository-index setup as JSON
94
+
95
+ <!-- END FORGELOOP GENERATED: cli:index-setup:options -->
96
+
97
+ ### `index-start`
98
+
99
+ Starts the ForgeLoop-owned Repository Index watcher after a complete index is
100
+ available. A verified healthy server is reused.
101
+
102
+ - **Options**:
103
+
104
+ <!-- BEGIN FORGELOOP GENERATED: cli:index-start:options -->
105
+
106
+ - `--path <directory>`: target project directory (default: current directory)
107
+ - `--json`: emit repository-index start as JSON
108
+
109
+ <!-- END FORGELOOP GENERATED: cli:index-start:options -->
110
+
111
+ ### `index-stop`
112
+
113
+ Stops only a server whose repository, index, metadata, executable, and process
114
+ identity are verified as ForgeLoop-owned.
115
+
116
+ - **Options**:
117
+
118
+ <!-- BEGIN FORGELOOP GENERATED: cli:index-stop:options -->
119
+
120
+ - `--path <directory>`: target project directory (default: current directory)
121
+ - `--json`: emit repository-index stop as JSON
122
+
123
+ <!-- END FORGELOOP GENERATED: cli:index-stop:options -->
124
+
125
+ ### `index-status`
126
+
127
+ Reports normalized Repository Index engine, index, policy, watcher, and health
128
+ state without repairing or provisioning it.
129
+
130
+ Structured output is path-safe by default: it omits machine-local repository,
131
+ index, state, and binary paths. Use `doctor` when an explicitly diagnostic
132
+ surface needs local path details.
133
+
134
+ - **Options**:
135
+
136
+ <!-- BEGIN FORGELOOP GENERATED: cli:index-status:options -->
137
+
138
+ - `--path <directory>`: target project directory (default: current directory)
139
+ - `--json`: emit repository-index health as JSON
140
+
141
+ <!-- END FORGELOOP GENERATED: cli:index-status:options -->
142
+
143
+ ### `index-rebuild`
144
+
145
+ Rebuilds only the derived Repository Index cache and restarts its owned
146
+ watcher. ForgeLoop task and protocol artifacts remain outside the deletion
147
+ boundary.
148
+
149
+ - **Options**:
150
+
151
+ <!-- BEGIN FORGELOOP GENERATED: cli:index-rebuild:options -->
152
+
153
+ - `--path <directory>`: target project directory (default: current directory)
154
+ - `--asset <path>`: use a preloaded pinned tgrep archive instead of downloading
155
+ - `--json`: emit repository-index rebuild as JSON
156
+
157
+ <!-- END FORGELOOP GENERATED: cli:index-rebuild:options -->
158
+
159
+ ### `search`
160
+
161
+ Searches the managed Repository Index through the provider-neutral structured
162
+ search contract. Native tgrep flags are not accepted as a generic pass-through.
163
+
164
+ The first query performs strong setup checks. Warm queries reuse process-local
165
+ per-repository readiness and avoid repeated `tgrep --version`, native status,
166
+ and process-inspection commands. A server/index failure gets one bounded
167
+ setup-and-retry attempt; native exit code `1` is a successful empty result.
168
+
169
+ - **Options**:
170
+
171
+ <!-- BEGIN FORGELOOP GENERATED: cli:search:options -->
172
+
173
+ - `--path <directory>`: target project directory (default: current directory)
174
+ - `<pattern>`: regular expression or literal search pattern
175
+ - `--glob <glob>`: include files matching a glob (repeatable)
176
+ - `--type <type>`: include files of a tgrep type (repeatable)
177
+ - `--fixed-strings`: treat the pattern as a literal string
178
+ - `--ignore-case`: search case-insensitively
179
+ - `--smart-case`: use case-insensitive search only for lowercase patterns
180
+ - `--word-regexp`: match whole words only
181
+ - `--context <lines>`: lines of context before and after matches
182
+ - `--before-context <lines>`: lines of context before matches
183
+ - `--after-context <lines>`: lines of context after matches
184
+ - `--max-count <number>`: maximum matches per file
185
+ - `--files-with-matches`: return matching file paths only
186
+ - `--stats`: include observed native search statistics
187
+ - `--json`: emit normalized provider-neutral search JSON
188
+
189
+ <!-- END FORGELOOP GENERATED: cli:search:options -->
190
+
79
191
  ## Workspace, Handoff, Responsibility, Scope, and Attestation
80
192
 
81
193
  These commands add optional, task-scoped protocol artifacts. They do not turn
@@ -11,7 +11,7 @@ ForgeLoop strictly separates normative protocol definitions from operational doc
11
11
  | Area | Location | Responsibility | Rule |
12
12
  | --- | --- | --- | --- |
13
13
  | **Normative Protocol** | Root (`LOOP_ENGINEERING.md`, `PROTOCOL_INTEGRATION.md`, `LOOP_SYSTEM_DESIGN.md`, `THREAT_MODEL.md`, `EXECUTION_STATE.md`) | Canonical authority for protocol rules, schemas, state transitions, and security | Never duplicate normative rules in sub-documents; link back to root files. |
14
- | **Operational & Reference** | `docs/` (`GETTING_STARTED.md`, `CROSS_HARNESS_CONTINUITY.md`, `CLI_REFERENCE.md`, `ARTIFACT_REFERENCE.md`, `TROUBLESHOOTING.md`, `RECIPES.md`) | Tutorials, command reference, handoff workflows, and troubleshooting | Explains how to operate the system. Links to normative sources for formal specifications. |
14
+ | **Operational & Reference** | `docs/` (`GETTING_STARTED.md`, `CROSS_HARNESS_CONTINUITY.md`, `CLI_REFERENCE.md`, `ARTIFACT_REFERENCE.md`, `TROUBLESHOOTING.md`, `RECIPES.md`, `REPOSITORY_INDEX.md`, `PERSISTENT_SEARCH_TRANSPORT.md`) | Tutorials, command reference, handoff workflows, repository search, transport behavior, and troubleshooting | Explains how to operate the system. Links to normative sources for formal specifications. |
15
15
  | **Domain Engineering** | `ENG/` (`clean-code-eng.md`, `design-code-eng.md`, `test-code-eng.md`, etc.) | Domain-specific implementation and quality standards | Frontmatter must adhere to `validate_loop_system.py` standards. |
16
16
  | **Consumer Documentation Quality** | [`ENG/documentation-quality-eng.md`](../ENG/documentation-quality-eng.md) | Quality standards for documentation work in projects using ForgeLoop | Governs client/consumer project documentation tasks via guide routing. |
17
17
  | **Visual Architecture** | `docs/diagrams/manifest.json` + the three typed workflow sources under `docs/diagrams/` | Governance metadata and canonical typed Archify workflow sources | Animated HTML explorers, animated SVG fallbacks, deterministic receipts, and source-bound human reviews are committed under `docs/assets/diagrams/` and `docs/diagrams/reviews/`. |
@@ -34,6 +34,8 @@ Documentation routing -> DOCS_INDEX.md
34
34
  Integration API truth -> src/integration.js (exports, envelope, limits, risk classes, resources)
35
35
  MCP behavior truth -> integrations/mcp/src/* and integrations/mcp/package.json
36
36
  MCP package boundary -> MCP package tests + scripts/mcp-package-smoke.mjs
37
+ Repository Index truth -> src/repository-index/*, CLI definitions, Integration API, and MCP resource registry
38
+ Persistent transport truth -> src/persistent-transport/*, CLI search dispatcher, and transport tests
37
39
  ```
38
40
 
39
41
  Operational documentation must explain canonical behavior, not redefine it.
@@ -129,6 +131,8 @@ conformance checks detect omissions.
129
131
  | **Discovery resume rules** | `DISCOVERY_SURFACES` & `nativeShim` | `scripts/validate_documentation_conformance.mjs` |
130
132
  | **Task-layout path freshness** | `TASK_LAYOUT_DOCUMENTS` & `task-paths.js` | `scripts/validate_documentation_conformance.mjs` |
131
133
  | **Package-shipped docs and runtime** | `package.json` (`files`) + `docs/PACKAGE_CONTENTS.md` | `tests/package.test.js` + `scripts/package_smoke.mjs` |
134
+ | **Repository Index contract** | `src/repository-index/*`, `src/core/cli-command-definitions.js`, `src/integration.js` | Repository Index unit/native tests + `scripts/verify-tgrep-manifest.mjs` |
135
+ | **Persistent CLI search transport** | `src/persistent-transport/*`, `src/commands/repository-index.js`, `src/repository-index/search.js` | Persistent transport unit/native tests + Repository Index integration tests |
132
136
  | **Architecture and trust diagrams** | `docs/diagrams/manifest.json` plus each typed workflow source | `scripts/check-documentation-diagrams.mjs` and `scripts/documentation-diagram-inventory.mjs` |
133
137
 
134
138
  ---
@@ -204,10 +208,11 @@ requires an explicit mapping and tests before activation.
204
208
 
205
209
  ## 8. README Hero and Package Boundary
206
210
 
207
- README hero assets are branding/conceptual illustrations. They are not the
208
- canonical protocol diagram. The typed Archify workflow under `docs/diagrams/`
209
- remains the canonical architecture flow source, with generated outputs under
210
- `docs/assets/diagrams/`.
211
+ README hero assets are branding/conceptual architecture illustrations. They are
212
+ not the canonical protocol diagram. The typed Archify workflow under
213
+ `docs/diagrams/` remains the canonical lifecycle architecture source, with
214
+ generated outputs under `docs/assets/diagrams/`; the CLI-only persistent search
215
+ transport is explained by `docs/PERSISTENT_SEARCH_TRANSPORT.md`.
211
216
 
212
217
  The README hero is intentionally GitHub-repository-only:
213
218
 
@@ -99,6 +99,23 @@ What `init` does:
99
99
  - Installs the canonical instruction kit under `.forgeloop/kit/`;
100
100
  - Places native discovery shims at the project root (`AGENTS.md`, `CLAUDE.md`, `.cursor/rules/`, `.github/copilot-instructions.md`);
101
101
  - Creates `.forgeloop/` for project configuration and `.forgeloop/task-state/` for isolated task execution.
102
+ - For a Git repository, provisions the pinned managed Repository Index, builds
103
+ its derived cache under `.forgeloop/repository-index/tgrep/`, starts the
104
+ owned watcher, and verifies readiness. The first setup may need network
105
+ access; use `forgeloop index-setup --asset <absolute-archive>` for an
106
+ explicitly preloaded release asset.
107
+
108
+ Repository discovery uses the same canonical service from every transport:
109
+
110
+ ```bash
111
+ forgeloop index-status --json
112
+ forgeloop search "ExecutionReceipt" --json
113
+ ```
114
+
115
+ The index is a disposable local cache. Its matches help an agent find relevant
116
+ files but do not define verification scope, evidence, task ownership, or
117
+ completion truth. Read [`REPOSITORY_INDEX.md`](./REPOSITORY_INDEX.md) for the
118
+ full command, Integration API, MCP, platform, offline, and security contract.
102
119
 
103
120
  ---
104
121
 
package/docs/MCP.md CHANGED
@@ -56,6 +56,21 @@ Capability flags (process-scoped, immutable after launch):
56
56
  - `forgeloop://task/{taskId}/context` — bounded profile-aware host context
57
57
  - `forgeloop://task/{taskId}/evaluations`
58
58
  - `forgeloop://project/capability-policy`
59
+ - `forgeloop://repository/index-status` — mandatory Repository Index health,
60
+ pinned engine, policy, and owned-server projection
61
+
62
+ The `forgeloop_search` tool is the read-only MCP projection of the canonical
63
+ provider-neutral Repository Search command. It accepts bounded search inputs
64
+ and returns project-relative normalized matches without machine-local root,
65
+ index, state, or binary paths; it does not accept raw tgrep arguments, arbitrary
66
+ binaries, or a no-index bypass. Setup/start/stop/rebuild
67
+ remain maintenance commands and are launch-capability gated.
68
+
69
+ MCP calls the canonical Repository Search service directly. It does not use
70
+ the CLI's user-scoped persistent search host or its local IPC endpoint. The
71
+ transport distinction, host lifecycle, ownership proof, bounded recovery, and
72
+ privacy projection are documented in
73
+ [`PERSISTENT_SEARCH_TRANSPORT.md`](./PERSISTENT_SEARCH_TRANSPORT.md).
59
74
 
60
75
  The durable-action resources are read-only projections. The first release does
61
76
  not expose `run-action` or host-attestation minting over MCP. An action that is
@@ -135,7 +150,7 @@ forgeloop-mcp-http --project /repo --mode safe # 127.0.0.1:3333
135
150
 
136
151
  | Component | Current contract |
137
152
  | --- | --- |
138
- | ForgeLoop core package | `>=1.5.0 <2` dependency range; current release `1.10.2` |
153
+ | ForgeLoop core package | `>=1.5.0 <2` dependency range; current release candidate `1.11.0` |
139
154
  | ForgeLoop protocol | `1` |
140
155
  | Integration API | `1` |
141
156
  | MCP package | `0.1.x` initial package |