phasegate 0.160.12 → 0.160.13

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.
package/README.md CHANGED
@@ -102,6 +102,15 @@ npx phasegate doctor
102
102
 
103
103
  `install` merges PhaseGate into the current project without discarding existing Claude/Codex hooks or Husky scripts. It reports planned changes before writing, adds package scripts and the `phasegate` devDependency, creates agent skill links, writes `AGENTS.md` / `CLAUDE.md` PhaseGate managed sections for the selected agent targets, writes the CI workflow when missing, and records managed files in `.phasegate/manifest.json`. If an existing file needs a forced managed update, run `npx phasegate install --apply --force`; PhaseGate backs up replaced files under `.phasegate/backups/`. <!-- @work-item-id WI-174 -->
104
104
 
105
+ For personal evaluation inside a team-owned repository, use local-only install:
106
+
107
+ ```bash
108
+ npx phasegate install --personal --dry-run
109
+ npx phasegate install --personal --apply
110
+ ```
111
+
112
+ `--personal` does not plan or write `package.json`, `AGENTS.md`, `CLAUDE.md`, `.husky/*`, `.github/workflows/*`, or `.gitignore`. It creates `.phasegate-local/config.json`, adds a managed local-only block to `.git/info/exclude`, records personal artifacts in `.phasegate/manifest.json`, and reports Codex user-level hook setup as a manual action instead of writing `.codex/hooks.json`. <!-- @work-item-id WI-207 -->
113
+
105
114
  For agent-driven setup planning, use:
106
115
 
107
116
  ```bash
@@ -12,6 +12,7 @@ Start with one question: what kind of repository are you setting up?
12
12
  |---|---|---|
13
13
  | New project with agent hooks | `npx phasegate init --name <project> --agent both --with-husky --with-ci` | `phasegate.config.json`, skills, hooks, agent context files, Husky, and CI targets exist |
14
14
  | Existing repository | `npx phasegate install --dry-run` then `npx phasegate install --apply` | Existing hooks/scripts are preserved and `.phasegate/manifest.json` records managed targets |
15
+ | Personal evaluation in a team repository | `npx phasegate install --personal --dry-run` then `npx phasegate install --personal --apply` | Team-owned files stay untouched; `.phasegate-local/config.json` and `.git/info/exclude` local-only entries are recorded |
15
16
  | CI-only rollout | `npx phasegate setup:agent --intent ci-only --with-ci --dry-run --json` | The plan explains CI changes without requiring local hooks |
16
17
  | Codex-only project | `npx phasegate init --agent codex --with-husky` | `.codex/hooks.json`, `AGENTS.md`, `.codex/skills`, and pre-commit backstop are present |
17
18
  | Strict validation rollout | `npx phasegate setup:agent --intent strict --dry-run --json` | The plan lists strict checks, L4 risk, rollback, and validation commands |
@@ -58,6 +58,15 @@ npx phasegate doctor
58
58
 
59
59
  `install --dry-run` reports whether each target will be created, merged, skipped, or refused. `install --apply` performs the merge, adds package scripts and the `phasegate` devDependency, creates `.claude/skills` and `.codex/skills` links, writes `CLAUDE.md` / `AGENTS.md` managed sections for selected agent targets, writes `.github/workflows/phasegate-aidlc-gate.yml` when CI is enabled, and records managed entries in `.phasegate/manifest.json`. See [Setup Artifacts](setup-artifacts.md) for the full managed target, generated artifact, runtime state, legacy artifact, and user-level setting inventory. <!-- @work-item-id WI-152 --> <!-- @work-item-id WI-169 --> <!-- @work-item-id WI-174 -->
60
60
 
61
+ For personal evaluation inside a team-owned repository:
62
+
63
+ ```bash
64
+ npx phasegate install --personal --dry-run
65
+ npx phasegate install --personal --apply
66
+ ```
67
+
68
+ Personal install keeps team-owned files out of both the plan and apply path: `package.json`, `AGENTS.md`, `CLAUDE.md`, `.husky/*`, `.github/workflows/*`, and `.gitignore` are not touched. PhaseGate writes only local artifacts: `.phasegate-local/config.json`, `.phasegate/manifest.json`, and a managed block in `.git/info/exclude`. Codex user-level hook setup is reported as a manual action instead of writing project-local `.codex/hooks.json`. <!-- @work-item-id WI-207 -->
69
+
61
70
  For agent-readable planning before writing files:
62
71
 
63
72
  ```bash
@@ -24,6 +24,15 @@ npx phasegate baseline --dry-run
24
24
 
25
25
  Use this when a repository already has meaningful history or custom automation. Treat any refused target as an agent-assisted review task instead of forcing it blindly.
26
26
 
27
+ ## Personal Evaluation Recipe
28
+
29
+ ```bash
30
+ npx phasegate install --personal --dry-run
31
+ npx phasegate install --personal --apply
32
+ ```
33
+
34
+ Use this inside a team-owned repository when you want local PhaseGate artifacts without changing `package.json`, agent context files, Husky hooks, CI workflows, or team `.gitignore`. <!-- @work-item-id WI-207 -->
35
+
27
36
  ## Agent Hooks Recipe
28
37
 
29
38
  ```bash
@@ -14,6 +14,7 @@ PhaseGate setup is more than `phasegate.config.json`. A healthy installation is
14
14
  | Configuration | `phasegate.config.json`, `package.json` | User owned, PhaseGate assisted | Created by `init`; `install` may merge scripts/devDependency into `package.json` |
15
15
  | Generated artifact | `.phasegate/manifest.json`, `.phasegate/backups/*`, `.phasegate/uninstalled-*.json`, `.phasegate/baseline.json` | PhaseGate | Written by lifecycle commands and validators; safe to regenerate only through the owning command |
16
16
  | Runtime state/report | `.phasegate/hook-skip-events.jsonl`, explicit `doctor --report-out <path>` output, `reports/regression/*`, resolved `reporting.outputDir` reports | PhaseGate command output | Produced while hooks, doctor, and validation commands run |
17
+ | Personal install artifact | `.phasegate-local/config.json`, `.git/info/exclude` PhaseGate block | One developer on one machine | Created by `phasegate install --personal`; team `.gitignore` and team-owned files are not modified |
17
18
  | Legacy artifact | `.harness-hooks.yml`, old Fuse hook files, `.harness/session-state.json`, `.harness/context-priority.json`, `.harness/reports` fallback | Compatibility only | Not required for current install lifecycle unless a project intentionally keeps an archived integration |
18
19
  | User-level setting | Codex CLI `hooks` feature flag | User machine | Must be enabled manually with `codex features enable hooks`; project commands do not modify it |
19
20
 
@@ -0,0 +1,6 @@
1
+ .phasegate/
2
+ .phasegate-local/
3
+ .codex/
4
+ .claude/
5
+ skills/
6
+ phasegate.config.json
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": "1.0",
3
+ "project": {
4
+ "name": "personal-phasegate"
5
+ },
6
+ "personal": true
7
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "phasegate",
3
- "version": "0.160.12",
3
+ "version": "0.160.13",
4
4
  "packageManager": "pnpm@10.30.1",
5
5
  "description": "Phasegate — AI-agnostic quality defense toolkit. Enforces structural integrity between design intent and code.",
6
6
  "license": "MIT",
@@ -7,6 +7,7 @@
7
7
  // @work-item-id WI-177
8
8
  // @work-item-id WI-182
9
9
  // @work-item-id WI-183
10
+ // @work-item-id WI-207
10
11
 
11
12
  import { mkdir, readFile, writeFile, copyFile, chmod, access, lstat, readlink, symlink } from "node:fs/promises";
12
13
  import { dirname, join } from "node:path";
@@ -18,7 +19,7 @@ import type { ManifestRepositoryPort } from "../ports/manifest-repository-port.j
18
19
  import type { HashCalculatorPort } from "../ports/hash-calculator-port.js";
19
20
 
20
21
  type InstallAction = "missing" | "will-merge" | "will-skip" | "will-overwrite";
21
- type StrategyType = "json" | "shell" | "yaml-add" | "package-json" | "markdown-managed";
22
+ type StrategyType = "json" | "shell" | "yaml-add" | "package-json" | "markdown-managed" | "text-managed" | "copy";
22
23
 
23
24
  export interface InstallPlanItem {
24
25
  readonly path: string;
@@ -45,6 +46,7 @@ export interface RunInstallInput {
45
46
  readonly skillSet?: "core" | "all";
46
47
  readonly workflow?: "standard" | "strict";
47
48
  readonly agent?: "claude" | "codex" | "both";
49
+ readonly personal?: boolean;
48
50
  }
49
51
 
50
52
  export interface RunInstallResult {
@@ -79,6 +81,8 @@ const SHELL_BEGIN = "# === phasegate managed (BEGIN) ===";
79
81
  const SHELL_END = "# === phasegate managed (END) ===";
80
82
  const MARKDOWN_BEGIN = "<!-- phasegate:managed-section:start -->";
81
83
  const MARKDOWN_END = "<!-- phasegate:managed-section:end -->";
84
+ const TEXT_BEGIN = "# phasegate personal install exclude (BEGIN)";
85
+ const TEXT_END = "# phasegate personal install exclude (END)";
82
86
 
83
87
  function isRecord(value: unknown): value is Record<string, unknown> {
84
88
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -152,6 +156,14 @@ function mergeShell(existing: string | null, incoming: string): string {
152
156
  return `${existing.replace(/\s*$/, "\n\n")}${block}\n`;
153
157
  }
154
158
 
159
+ function mergeTextManaged(existing: string | null, incoming: string): string {
160
+ const block = `${TEXT_BEGIN}\n${incoming.trim()}\n${TEXT_END}`;
161
+ if (existing === null || existing.trim().length === 0) return `${block}\n`;
162
+ const pattern = new RegExp(`${escapeRegExp(TEXT_BEGIN)}[\\s\\S]*?${escapeRegExp(TEXT_END)}`);
163
+ if (pattern.test(existing)) return existing.replace(pattern, block).replace(/\s*$/, "\n");
164
+ return `${existing.replace(/\s*$/, "\n\n")}${block}\n`;
165
+ }
166
+
155
167
  function managedMarkdownBlock(content: string): string {
156
168
  const start = content.indexOf(MARKDOWN_BEGIN);
157
169
  const end = content.indexOf(MARKDOWN_END);
@@ -282,7 +294,9 @@ export class RunInstallUseCase {
282
294
  const skillSet = input.skillSet ?? "all";
283
295
  const workflow = input.workflow ?? "standard";
284
296
  const agent = input.agent ?? (includeClaude && includeCodex ? "both" : includeCodex ? "codex" : "claude");
285
- const targets = this.createTargets({ includeClaude, includeCodex, includeHusky, includeCi });
297
+ const targets = input.personal
298
+ ? this.createPersonalTargets()
299
+ : this.createTargets({ includeClaude, includeCodex, includeHusky, includeCi });
286
300
  const existingManifest = await this.manifestRepository.load(input.projectRoot);
287
301
  const baseManifest = existingManifest ?? DeploymentManifest.create(input.phasegateVersion);
288
302
  let manifest = baseManifest;
@@ -363,7 +377,7 @@ export class RunInstallUseCase {
363
377
  }
364
378
  }
365
379
 
366
- const linkPaths = [
380
+ const linkPaths = input.personal ? [] : [
367
381
  ...(includeClaude ? [".claude/skills"] : []),
368
382
  ...(includeCodex ? [".codex/skills"] : []),
369
383
  ];
@@ -400,6 +414,19 @@ export class RunInstallUseCase {
400
414
  }
401
415
  }
402
416
 
417
+ if (input.personal && includeCodex) {
418
+ plan.push({
419
+ path: "~/.codex/hooks.json",
420
+ action: "will-skip",
421
+ repairMode: "manual",
422
+ strategy: "json",
423
+ changed: false,
424
+ summary: "~/.codex/hooks.json: personal mode does not write user-level Codex settings; configure hooks manually",
425
+ diff: "manual user-level Codex hook setup required",
426
+ skillHint: null,
427
+ });
428
+ }
429
+
403
430
  if (input.apply && changed.length > 0) {
404
431
  try {
405
432
  await this.manifestRepository.save(input.projectRoot, manifest);
@@ -498,8 +525,26 @@ export class RunInstallUseCase {
498
525
  ];
499
526
  }
500
527
 
528
+ private createPersonalTargets(): readonly InstallTarget[] {
529
+ return [
530
+ {
531
+ path: ".phasegate-local/config.json",
532
+ strategy: "copy" as const,
533
+ templatePath: "docs/templates/personal/phasegate-local-config.json",
534
+ },
535
+ {
536
+ path: ".git/info/exclude",
537
+ strategy: "text-managed" as const,
538
+ templatePath: "docs/templates/personal/git-info-exclude",
539
+ block: { start: TEXT_BEGIN, end: TEXT_END, content: "phasegate personal install exclude block" },
540
+ },
541
+ ];
542
+ }
543
+
501
544
  private repairMode(target: InstallTarget, before: string | null): RepairMode {
502
545
  if (target.strategy === "shell") return shellRepairMode(before);
546
+ if (target.strategy === "text-managed") return "mechanical";
547
+ if (target.strategy === "copy") return "mechanical";
503
548
  if (target.strategy === "json") return jsonRepairMode(before);
504
549
  if (target.strategy === "markdown-managed") return "mechanical";
505
550
  return "mechanical";
@@ -513,7 +558,9 @@ export class RunInstallUseCase {
513
558
 
514
559
  private merge(target: InstallTarget, before: string | null, template: string, version: string): string {
515
560
  if (target.strategy === "yaml-add") return before ?? template;
561
+ if (target.strategy === "copy") return before ?? template;
516
562
  if (target.strategy === "shell") return mergeShell(before, template);
563
+ if (target.strategy === "text-managed") return mergeTextManaged(before, template);
517
564
  if (target.strategy === "markdown-managed") return mergeManagedMarkdown(before, template);
518
565
  if (target.strategy === "package-json") {
519
566
  const existing = before === null ? {} : (JSON.parse(before) as unknown);
@@ -3,6 +3,7 @@
3
3
  // @work-item-id WI-147
4
4
  // @work-item-id WI-174
5
5
  // @work-item-id WI-199
6
+ // @work-item-id WI-207
6
7
 
7
8
  import { access, copyFile, lstat, mkdir, readFile, readlink, rm, rmdir, writeFile } from "node:fs/promises";
8
9
  import { dirname, join, relative, resolve } from "node:path";
@@ -12,7 +13,7 @@ import type { HashCalculatorPort } from "../ports/hash-calculator-port.js";
12
13
  import type { ManifestRepositoryPort } from "../ports/manifest-repository-port.js";
13
14
 
14
15
  type UninstallAction = "missing-manifest" | "delete" | "unlink" | "reverse-merge" | "skip" | "refuse";
15
- type StrategyType = "created" | "json" | "shell" | "package-json" | "markdown-managed" | "symlink" | "yaml-add" | "unknown";
16
+ type StrategyType = "created" | "json" | "shell" | "package-json" | "markdown-managed" | "symlink" | "yaml-add" | "text-managed" | "unknown";
16
17
 
17
18
  export interface UninstallPlanItem {
18
19
  readonly path: string;
@@ -47,6 +48,8 @@ const SHELL_BEGIN = "# === phasegate managed (BEGIN) ===";
47
48
  const SHELL_END = "# === phasegate managed (END) ===";
48
49
  const MARKDOWN_BEGIN = "<!-- phasegate:managed-section:start -->";
49
50
  const MARKDOWN_END = "<!-- phasegate:managed-section:end -->";
51
+ const TEXT_BEGIN = "# phasegate personal install exclude (BEGIN)";
52
+ const TEXT_END = "# phasegate personal install exclude (END)";
50
53
  const PHASEGATE_SCRIPT_PREFIX = "phasegate:";
51
54
  const PROTECTED_UNINSTALL_PATHS = new Set(["package.json", "package-lock.json"]);
52
55
 
@@ -119,6 +122,11 @@ export function reverseManagedMarkdown(currentContent: string): string {
119
122
  return currentContent.replace(pattern, "\n").replace(/\n{3,}/g, "\n\n").replace(/\s*$/, "\n").replace(/^\n/, "");
120
123
  }
121
124
 
125
+ export function reverseTextManaged(currentContent: string): string {
126
+ const pattern = new RegExp(`\\n?${escapeRegExp(TEXT_BEGIN)}[\\s\\S]*?${escapeRegExp(TEXT_END)}\\n?`);
127
+ return currentContent.replace(pattern, "\n").replace(/\n{3,}/g, "\n\n").replace(/\s*$/, "\n").replace(/^\n/, "");
128
+ }
129
+
122
130
  export function reversePackageJsonMerge(currentContent: string): string {
123
131
  const parsed = JSON.parse(currentContent) as unknown;
124
132
  const result = isRecord(parsed) ? { ...parsed } : {};
@@ -312,6 +320,7 @@ export class RunUninstallUseCase {
312
320
  private async reverseMerged(harnessRoot: string, path: string, currentContent: string, strategy: StrategyType): Promise<string> {
313
321
  if (strategy === "shell") return currentContent.includes(SHELL_BEGIN) ? reverseShellMerge(currentContent) : currentContent;
314
322
  if (strategy === "markdown-managed") return currentContent.includes(MARKDOWN_BEGIN) ? reverseManagedMarkdown(currentContent) : currentContent;
323
+ if (strategy === "text-managed") return currentContent.includes(TEXT_BEGIN) ? reverseTextManaged(currentContent) : currentContent;
315
324
  if (strategy === "package-json") return reversePackageJsonMerge(currentContent);
316
325
  if (strategy === "json") return reverseJsonMerge(currentContent, await readFile(join(harnessRoot, this.templateFor(path)), "utf8"));
317
326
  throw new Error(`Unsupported merged strategy: ${strategy}`);
@@ -322,6 +331,7 @@ export class RunUninstallUseCase {
322
331
  if (mode === "created") return path.endsWith(".yml") || path.endsWith(".yaml") ? "yaml-add" : "created";
323
332
  if (path === "package.json") return "package-json";
324
333
  if (path === "AGENTS.md" || path === "CLAUDE.md") return "markdown-managed";
334
+ if (path === ".git/info/exclude") return "text-managed";
325
335
  if (path.endsWith(".json")) return "json";
326
336
  if (path.startsWith(".husky/")) return "shell";
327
337
  return "unknown";
@@ -2,6 +2,7 @@
2
2
  // @layer presentation
3
3
  // @work-item-id WI-146
4
4
  // @work-item-id WI-175
5
+ // @work-item-id WI-207
5
6
 
6
7
  import type { RunInstallUseCase } from "../../application/usecases/run-install.js";
7
8
 
@@ -20,6 +21,7 @@ export interface InstallHandlerInput {
20
21
  readonly skillSet?: "core" | "all";
21
22
  readonly workflow?: "standard" | "strict";
22
23
  readonly agent?: "claude" | "codex" | "both";
24
+ readonly personal?: boolean;
23
25
  }
24
26
 
25
27
  export interface InstallHandlerResult {
@@ -39,7 +41,7 @@ export class InstallHandler {
39
41
  };
40
42
  }
41
43
  const lines = [
42
- input.apply ? "phasegate install apply" : "phasegate install dry-run",
44
+ input.apply ? `phasegate install${input.personal ? " --personal" : ""} apply` : `phasegate install${input.personal ? " --personal" : ""} dry-run`,
43
45
  ...result.plan.map((item) => {
44
46
  const hint = item.skillHint ? `; hint: ${item.skillHint}` : "";
45
47
  return `- ${item.path}: ${item.action} (${item.repairMode}, ${item.strategy}); diff: ${item.diff}${hint}`;
@@ -171,7 +171,7 @@ Setup:
171
171
  scaffold-wi <unit|_cross> <story|issue|chore>
172
172
  Create docs/inception/{unit}/WI-XXX/description.md
173
173
  emit-agent-rules Print AGENTS.md / CLAUDE.md WI workflow rules block
174
- install Install phasegate managed files (--dry-run|--apply, --force)
174
+ install Install phasegate managed files (--dry-run|--apply, --force, --personal)
175
175
  uninstall Uninstall phasegate managed files (--dry-run|--apply, --force)
176
176
  reconcile Reconcile phasegate managed files (--dry-run|--apply, --force)
177
177
  setup:agent Diagnose repo setup and produce/apply an agent-readable setup plan
@@ -625,6 +625,7 @@ Options:
625
625
  --workflow <standard|strict> Rendered agent context workflow mode (default: standard)
626
626
  --with-husky Include Husky hook targets
627
627
  --with-ci Include GitHub Actions target
628
+ --personal Use local-only install: no package.json, agent docs, Husky, CI, or .gitignore writes
628
629
  --json Output machine-readable JSON
629
630
  --help, -h Show this help`,
630
631
  "setup:agent": `Usage: phasegate setup:agent [options]
@@ -2045,7 +2046,7 @@ async function main(): Promise<void> {
2045
2046
  }
2046
2047
 
2047
2048
  case "install": {
2048
- const KNOWN_INSTALL_FLAGS = ["--dry-run", "--apply", "--force", "--json", "--agent", "--skills", "--workflow", "--with-husky", "--with-ci"];
2049
+ const KNOWN_INSTALL_FLAGS = ["--dry-run", "--apply", "--force", "--json", "--agent", "--skills", "--workflow", "--with-husky", "--with-ci", "--personal"];
2049
2050
  const flagError = validateKnownFlags(args, KNOWN_INSTALL_FLAGS);
2050
2051
  if (flagError) {
2051
2052
  console.error(flagError);
@@ -2066,6 +2067,7 @@ async function main(): Promise<void> {
2066
2067
  }
2067
2068
  const includeClaude = agent === "claude" || agent === "both";
2068
2069
  const includeCodex = agent === "codex" || agent === "both";
2070
+ const personal = hasFlag(args, "--personal");
2069
2071
  const mod = createInstallationModule();
2070
2072
  const phasegateVersion = await getHarnessVersion(harnessRoot);
2071
2073
  const result = await mod.installHandler.execute({
@@ -2077,11 +2079,12 @@ async function main(): Promise<void> {
2077
2079
  force: hasFlag(args, "--force"),
2078
2080
  includeClaude,
2079
2081
  includeCodex,
2080
- includeHusky: true,
2081
- includeCi: true,
2082
+ includeHusky: personal ? false : true,
2083
+ includeCi: personal ? false : true,
2082
2084
  skillSet: skillSetRaw,
2083
2085
  workflow: parseWorkflowMode(workflowRaw),
2084
2086
  agent,
2087
+ personal,
2085
2088
  json,
2086
2089
  });
2087
2090
  console.log(result.stdout);
package/skills/README.md CHANGED
@@ -16,6 +16,8 @@
16
16
 
17
17
  `.agent/skills` は旧 setup 由来の互換パスです。新規導入では管理対象にしません。<!-- @work-item-id WI-157 -->
18
18
 
19
+ `phasegate install --personal` はチーム所有リポジトリでの個人評価用です。このモードでは `.claude/skills` / `.codex/skills` のリンクを作成せず、`.phasegate-local/config.json` と `.git/info/exclude` の local-only managed block だけを扱います。通常の共有導入が必要になった時点で `phasegate install --dry-run` / `phasegate install --apply` を使います。<!-- @work-item-id WI-207 -->
20
+
19
21
  ## 新しいスキルの追加
20
22
 
21
23
  新しいスキルを追加する場合は、この `skills` ディレクトリに直接追加してください。あわせて `docs/guide/skills-overview.md`、README の skill 数、必要なら `skills/phasegate-toolkit-guide/SKILL.md` の参照先を更新します。シンボリックリンクを通じて、対応エージェントから利用可能になります。<!-- @work-item-id WI-154 -->
@@ -35,6 +35,8 @@ phasegate を導入した直後の config は単純な default で、実プロ
35
35
  | hook config | `.claude/scripts/hook-config.json` | 既存 hook 設定確認 |
36
36
  | doctor report | 明示された report path、またはユーザーが指定した `.phasegate/last-doctor-report.json` | `repairMode` / `repairHint` / `suggestedSkill` の確認 |
37
37
  | manifest | `.phasegate/manifest.json` | install / reconcile / uninstall の managed target と hash 状態確認 |
38
+ | personal config | `.phasegate-local/config.json` | `install --personal` の local-only 設定確認 |
39
+ | git local exclude | `.git/info/exclude` | `install --personal` の repository-local ignore block 確認 |
38
40
  | Claude hooks | `.claude/settings.json` | managed hook JSON と user customization の確認 |
39
41
  | Codex hooks | `.codex/hooks.json` | managed hook JSON と Codex hook 配線確認 |
40
42
  | Husky scripts | `.husky/pre-commit`, `.husky/commit-msg`, `.husky/pre-push` | pre-commit backstop と bypass audit の確認 |
@@ -127,6 +129,7 @@ product-architect で Unit を作り、いくつかの logical_design を書い
127
129
  #### 観点 9: setup lifecycle と doctor finding
128
130
 
129
131
  - `phasegate doctor --json` の finding に `repairMode: "ai-assisted"` と `suggestedSkill.skillName = "phasegate-config-doctor"` がある → 本 skill が merge 方針、保持する user content、実行すべき `install --apply` / `--force` / `reconcile --apply` を提案する
132
+ - チーム所有リポジトリで個人評価だけを行う相談では、通常の `install --apply` ではなく `phasegate install --personal --dry-run` を先に提案する。personal install は `package.json`, `AGENTS.md`, `CLAUDE.md`, `.husky/*`, `.github/workflows/*`, `.gitignore`, `.codex/hooks.json`, skill symlink を変更対象にしない。変更対象は `.phasegate-local/config.json`, `.phasegate/manifest.json`, `.git/info/exclude` の managed block に限定し、Codex user-level hook setup は manual action として扱う。<!-- @work-item-id WI-207 -->
130
133
  - Claude-only / Codex-only 導入後は `phasegate doctor --agent claude --json` または `phasegate doctor --agent codex --json` を使って selected agent の readiness を読む。`scopedOutFindings` は未選択 agent の `not-applicable` 情報なので、ユーザーがその agent を導入したいと言っていない限り repair 提案にしない。`repairHint: null` / `suggestedSkill: null` は意図的な抑制で、`currentScopeRepairTarget: false` と `repairModeApplicability: "only-if-agent-selected"` は raw `repairMode` が current scope の修復指示ではないという印である。<!-- @work-item-id WI-178, WI-179, WI-180 -->
131
134
  - `repairHint` がある mechanical finding → 原則として hint のコマンドを優先し、実行前に対象ファイルと manifest の差分を確認
132
135
  - manifest parse error → `.phasegate/manifest.json` を手で修復する前に backup / uninstall / reinstall の選択肢を提示
@@ -130,6 +130,8 @@ docs/guide/ # phasegate リポジトリ自体 (dogfood)
130
130
  - 既存プロジェクト導入: `docs/guide/retrofit-adoption.md`
131
131
  - setup artifact / doctor finding / legacy artifact: `docs/guide/setup-artifacts.md`
132
132
 
133
+ チーム所有リポジトリで個人評価だけを行いたい場合は、`docs/guide/installation.md` の personal install セクションを読む。`phasegate install --personal` は `package.json`、`AGENTS.md`、`CLAUDE.md`、`.husky/*`、`.github/workflows/*`、`.gitignore`、`.codex/hooks.json`、skill symlink を変更せず、`.phasegate-local/config.json` と `.git/info/exclude` の managed block を使う。Codex user-level hook setup は manual action として説明する。<!-- @work-item-id WI-207 -->
134
+
133
135
  `setup-artifacts.md` は managed target / generated artifact / runtime state / legacy artifact / user-level setting の分類を持つ。`doctor --report-out` は明示 path への出力で、`.phasegate/last-doctor-report.json` は固定生成物ではない点もここを参照する。<!-- @work-item-id WI-153 -->
134
136
 
135
137
  Claude-only / Codex-only setup の確認では、full `phasegate doctor` と scoped doctor を区別する。ユーザーが `setup:agent --agent claude` を選んだ場合は `phasegate doctor --agent claude --json` を優先し、`scopedOutFindings` の Codex finding は「未選択 agent の not-applicable 情報」であり修復対象ではないと説明する。`repairHint: null` / `suggestedSkill: null` は意図的な抑制で、`currentScopeRepairTarget: false` と `repairModeApplicability: "only-if-agent-selected"` は `repairMode` が current scope の修復指示ではないという印である。full doctor は両 agent を導入したい場合の診断として扱う。<!-- @work-item-id WI-178, WI-179, WI-180 -->