phasegate 0.159.0 → 0.160.1
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/CHANGELOG.md +12 -0
- package/docs/guide/cli-reference.md +1 -1
- package/docs/guide/configuration.md +35 -0
- package/docs/templates/ci/aidlc-gate.yml +17 -11
- package/docs/templates/hooks/pre-commit +8 -10
- package/package.json +2 -1
- package/scripts/harness/ci-governance/infrastructure/adapters/yaml-template-renderer-adapter.ts +1 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +11 -0
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +49 -0
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +49 -0
- package/scripts/harness/installation/application/usecases/run-install.ts +2 -0
- package/scripts/harness/main.ts +1 -1
- package/scripts/harness/skill-quality/composition-root.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.160.1] - 2026-05-14
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
|
|
14
|
+
- **WI-181 / WI-182 / WI-183 — downstream install and package contract** — declares `tinyglobby` as a packaged runtime dependency, updates pre-commit and AIDLC workflow templates to call the published `phasegate` bin instead of monorepo-only scripts, and makes the workflow choose npm/yarn/pnpm install commands from lockfiles.
|
|
15
|
+
|
|
16
|
+
## [0.160.0] - 2026-05-13
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- **WI-170 — phase2 initial-creation expiration public contract** — documents `p2:check-initial-creation` as a public compatibility command and adds schema/type support for `phase2Extensions.initialCreationExpirationRules` in v2 and v3 config documents.
|
|
21
|
+
|
|
10
22
|
## [0.159.0] - 2026-05-13
|
|
11
23
|
|
|
12
24
|
### Added
|
|
@@ -415,7 +415,7 @@ ISSUE-005 P3-10 で明確化された境界:
|
|
|
415
415
|
| `p2:check-freshness` | `--pattern <glob>` `--dry-run` `--format text\|json` | Compatibility entry point for L4-004 doc freshness; canonical L4 execution is `validate --layer L4` |
|
|
416
416
|
| `p2:validate-pointers` | `--include-urls` `--format text\|json` | Compatibility entry point for L4-005 pointer validation; canonical L4 execution is `validate --layer L4` |
|
|
417
417
|
| `p2:generate-e2e-template` | `--phase <phase>` `--output <path>` | Generate E2E test template |
|
|
418
|
-
| `p2:check-initial-creation` | `--pattern <glob>` `--format text\|json` |
|
|
418
|
+
| `p2:check-initial-creation` | `--pattern <glob>` `--format text\|json` | Public compatibility detector for long-lived `initial_creation: true` docs; configured by `phase2Extensions.initialCreationExpirationRules`. |
|
|
419
419
|
|
|
420
420
|
### `phasegate:generate-matrix`
|
|
421
421
|
|
|
@@ -75,6 +75,18 @@ The plan identifies target fields, managed artifacts, commands, validation, risk
|
|
|
75
75
|
"baseline": {
|
|
76
76
|
"enabled": true,
|
|
77
77
|
"path": ".phasegate/baseline.json"
|
|
78
|
+
},
|
|
79
|
+
"phase2Extensions": {
|
|
80
|
+
"initialCreationExpirationRules": [
|
|
81
|
+
{
|
|
82
|
+
"ruleId": "stale-initial-creation",
|
|
83
|
+
"documentPattern": "docs/**/*.md",
|
|
84
|
+
"daysThreshold": 90,
|
|
85
|
+
"commitCountThreshold": 5,
|
|
86
|
+
"evaluationMode": "or",
|
|
87
|
+
"enabled": true
|
|
88
|
+
}
|
|
89
|
+
]
|
|
78
90
|
}
|
|
79
91
|
}
|
|
80
92
|
```
|
|
@@ -179,6 +191,29 @@ Example for Python and TypeScript:
|
|
|
179
191
|
|
|
180
192
|
The metadata validators read `@unit` and `@layer` with language-agnostic regular expressions, so Python `# @unit api` and Go `// @unit api` style comments are both valid as long as the file extension is included here.
|
|
181
193
|
|
|
194
|
+
#### `phase2Extensions`
|
|
195
|
+
|
|
196
|
+
<!-- @work-item-id WI-170 -->
|
|
197
|
+
|
|
198
|
+
`phase2Extensions.initialCreationExpirationRules` is a public compatibility contract for `phasegate p2:check-initial-creation`. The command detects documents that still carry `traceability.initial_creation: true` after they have aged past configured thresholds. Regular scheduled drift checks should still run through `phasegate validate --layer L4`.
|
|
199
|
+
|
|
200
|
+
| Sub-field | Type | Default | Description |
|
|
201
|
+
|-----------|------|---------|-------------|
|
|
202
|
+
| `initialCreationExpirationRules` | `array` | built-in `90 days / 5 commits / or` rule | Rules used by `p2:check-initial-creation`. Omit to use the built-in rule. |
|
|
203
|
+
|
|
204
|
+
Rule fields:
|
|
205
|
+
|
|
206
|
+
| Field | Type | Description |
|
|
207
|
+
|-------|------|-------------|
|
|
208
|
+
| `ruleId` | `string` | Stable identifier shown in diagnostics. |
|
|
209
|
+
| `documentPattern` | `string` | Glob for candidate Markdown documents. |
|
|
210
|
+
| `daysThreshold` | `number` | Non-negative age threshold in days. |
|
|
211
|
+
| `commitCountThreshold` | `number` | Non-negative threshold for the number of commits touching the document. |
|
|
212
|
+
| `evaluationMode` | `"or"` \| `"and"` | `"or"` reports when either threshold is met; `"and"` requires both. |
|
|
213
|
+
| `enabled` | `boolean` | Optional. Defaults to `true`. |
|
|
214
|
+
|
|
215
|
+
Keep `initial_creation: true` only while a document is genuinely new and still being filled. Remove it once the expected initial content exists; otherwise this compatibility command reports the document after the configured age or commit-count threshold.
|
|
216
|
+
|
|
182
217
|
##### Phase Dependency Presets
|
|
183
218
|
|
|
184
219
|
| Preset | Phase 3 Gates | storyReflection default | Use Case |
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# Phasegate — PR検証ワークフロー
|
|
2
2
|
#
|
|
3
3
|
# 使い方:
|
|
4
|
-
#
|
|
4
|
+
# phasegate install または ci:generate-template で配置する。
|
|
5
5
|
#
|
|
6
6
|
# 実行タイミング: Pull Request(open / synchronize / reopen)
|
|
7
7
|
# 実行内容:
|
|
8
8
|
# 1. bypass:audit — bypass trailer / evidence 監査
|
|
9
|
-
# 2.
|
|
10
|
-
# 3.
|
|
9
|
+
# 2. phasegate lint — L1 Biome AST ルール検証
|
|
10
|
+
# 3. phasegate:ci-check — L3 CI バリデータ(security / performance / coverage / nyquist)
|
|
11
11
|
# 4. 失敗時: PR にエラーサマリーをコメント
|
|
12
12
|
|
|
13
13
|
name: AIDLC Quality Gate
|
|
@@ -33,15 +33,21 @@ jobs:
|
|
|
33
33
|
uses: actions/setup-node@v4
|
|
34
34
|
with:
|
|
35
35
|
node-version: '20'
|
|
36
|
-
cache: 'pnpm'
|
|
37
36
|
|
|
38
|
-
- name:
|
|
39
|
-
|
|
40
|
-
with:
|
|
41
|
-
version: 9
|
|
37
|
+
- name: Enable Corepack
|
|
38
|
+
run: corepack enable
|
|
42
39
|
|
|
43
40
|
- name: Install dependencies
|
|
44
|
-
run:
|
|
41
|
+
run: |
|
|
42
|
+
if [ -f pnpm-lock.yaml ]; then
|
|
43
|
+
pnpm install --frozen-lockfile
|
|
44
|
+
elif [ -f yarn.lock ]; then
|
|
45
|
+
yarn install --immutable || yarn install --frozen-lockfile
|
|
46
|
+
elif [ -f package-lock.json ] || [ -f npm-shrinkwrap.json ]; then
|
|
47
|
+
npm ci
|
|
48
|
+
else
|
|
49
|
+
npm install
|
|
50
|
+
fi
|
|
45
51
|
|
|
46
52
|
# Bypass audit: local `git commit --no-verify` can skip hooks, but CI
|
|
47
53
|
# replays the gate over the PR range and requires structured evidence.
|
|
@@ -63,7 +69,7 @@ jobs:
|
|
|
63
69
|
id: lint
|
|
64
70
|
run: |
|
|
65
71
|
set +e
|
|
66
|
-
RESULT=$(
|
|
72
|
+
RESULT=$(npx phasegate lint --json 2>&1)
|
|
67
73
|
EXIT_CODE=$?
|
|
68
74
|
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
69
75
|
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
@@ -77,7 +83,7 @@ jobs:
|
|
|
77
83
|
if: always()
|
|
78
84
|
run: |
|
|
79
85
|
set +e
|
|
80
|
-
RESULT=$(
|
|
86
|
+
RESULT=$(npx phasegate phasegate:ci-check --json 2>&1)
|
|
81
87
|
EXIT_CODE=$?
|
|
82
88
|
echo "result<<EOF" >> $GITHUB_OUTPUT
|
|
83
89
|
echo "$RESULT" >> $GITHUB_OUTPUT
|
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env sh
|
|
2
2
|
# GSDLC Quality Harness — Pre-commit Hook テンプレート
|
|
3
3
|
#
|
|
4
|
-
#
|
|
5
|
-
#
|
|
6
|
-
# 2. chmod +x .husky/pre-commit
|
|
7
|
-
# 3. pnpm add --save-dev husky && npx husky install
|
|
4
|
+
# Managed by phasegate install / ci:generate-template.
|
|
5
|
+
# Requires phasegate to be available through package.json devDependencies or npx.
|
|
8
6
|
#
|
|
9
7
|
# 実行内容:
|
|
10
8
|
# L1: Biome AST ルール(require-unit-comment, no-layer-violation など 8ルール)
|
|
@@ -15,7 +13,7 @@
|
|
|
15
13
|
|
|
16
14
|
. "$(dirname -- "$0")/_/husky.sh"
|
|
17
15
|
|
|
18
|
-
|
|
16
|
+
PHASEGATE_CMD="${PHASEGATE_CMD:-npx phasegate}"
|
|
19
17
|
|
|
20
18
|
echo "🔍 AIDLC Quality Gate (Pre-commit)"
|
|
21
19
|
echo "──────────────────────────────────"
|
|
@@ -24,14 +22,14 @@ echo "────────────────────────
|
|
|
24
22
|
# L1: Biome AST ルール
|
|
25
23
|
# -----------------------------------------------------------------------
|
|
26
24
|
echo "▶ L1 Lint (Biome AST)..."
|
|
27
|
-
$
|
|
25
|
+
$PHASEGATE_CMD lint
|
|
28
26
|
L1_EXIT=$?
|
|
29
27
|
|
|
30
28
|
if [ $L1_EXIT -ne 0 ]; then
|
|
31
29
|
echo ""
|
|
32
30
|
echo "❌ L1 Lint が失敗しました。"
|
|
33
31
|
echo " 修正してから再度コミットしてください。"
|
|
34
|
-
echo " 詳細:
|
|
32
|
+
echo " 詳細: npx phasegate lint"
|
|
35
33
|
exit 1
|
|
36
34
|
fi
|
|
37
35
|
echo "✅ L1 Lint: passed"
|
|
@@ -42,10 +40,10 @@ echo "✅ L1 Lint: passed"
|
|
|
42
40
|
# Quick Mode では phase-gate をスキップ
|
|
43
41
|
if [ "${HARNESS_QUICK_MODE:-0}" = "1" ]; then
|
|
44
42
|
echo "▶ L2 Validators (Quick Mode: phase-gate スキップ)..."
|
|
45
|
-
$
|
|
43
|
+
$PHASEGATE_CMD validate --layer L2 --format human --no-l4
|
|
46
44
|
else
|
|
47
45
|
echo "▶ L2 Validators (phase-gate / metadata / test-quality)..."
|
|
48
|
-
$
|
|
46
|
+
$PHASEGATE_CMD validate --layer L2 --format human
|
|
49
47
|
fi
|
|
50
48
|
L2_EXIT=$?
|
|
51
49
|
|
|
@@ -53,7 +51,7 @@ if [ $L2_EXIT -ne 0 ]; then
|
|
|
53
51
|
echo ""
|
|
54
52
|
echo "❌ L2 Validators が失敗しました。"
|
|
55
53
|
echo " 修正してから再度コミットしてください。"
|
|
56
|
-
echo " 詳細:
|
|
54
|
+
echo " 詳細: npx phasegate validate --layer L2 --format human"
|
|
57
55
|
exit 1
|
|
58
56
|
fi
|
|
59
57
|
echo "✅ L2 Validators: passed"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "phasegate",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.160.1",
|
|
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",
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"dependencies": {
|
|
65
65
|
"ajv": "^8.18.0",
|
|
66
66
|
"picomatch": "^4.0.4",
|
|
67
|
+
"tinyglobby": "^0.2.15",
|
|
67
68
|
"tsx": "^4.0.0"
|
|
68
69
|
},
|
|
69
70
|
"devDependencies": {
|
|
@@ -54,6 +54,7 @@ export interface HarnessConfigSourceDocument {
|
|
|
54
54
|
ci?: HarnessConfigResolvedDocument['ci'];
|
|
55
55
|
validate?: HarnessConfigResolvedDocument['validate'];
|
|
56
56
|
preCommit?: Partial<HarnessConfigResolvedDocument['preCommit']>;
|
|
57
|
+
phase2Extensions?: HarnessConfigResolvedDocument['phase2Extensions'];
|
|
57
58
|
architecture?: ArchitectureConfigSource;
|
|
58
59
|
}
|
|
59
60
|
|
|
@@ -122,6 +123,16 @@ export interface HarnessConfigResolvedDocument {
|
|
|
122
123
|
preCommit?: {
|
|
123
124
|
implementationExtensions: string[];
|
|
124
125
|
};
|
|
126
|
+
phase2Extensions?: {
|
|
127
|
+
initialCreationExpirationRules?: Array<{
|
|
128
|
+
ruleId: string;
|
|
129
|
+
documentPattern: string;
|
|
130
|
+
daysThreshold: number;
|
|
131
|
+
commitCountThreshold: number;
|
|
132
|
+
evaluationMode: 'or' | 'and';
|
|
133
|
+
enabled?: boolean;
|
|
134
|
+
}>;
|
|
135
|
+
};
|
|
125
136
|
architecture?: ArchitectureConfigDocument;
|
|
126
137
|
}
|
|
127
138
|
|
package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json
CHANGED
|
@@ -498,6 +498,55 @@
|
|
|
498
498
|
"minLength": 1
|
|
499
499
|
}
|
|
500
500
|
}
|
|
501
|
+
},
|
|
502
|
+
"phase2Extensions": {
|
|
503
|
+
"type": "object",
|
|
504
|
+
"additionalProperties": false,
|
|
505
|
+
"properties": {
|
|
506
|
+
"initialCreationExpirationRules": {
|
|
507
|
+
"type": "array",
|
|
508
|
+
"items": {
|
|
509
|
+
"type": "object",
|
|
510
|
+
"additionalProperties": false,
|
|
511
|
+
"required": [
|
|
512
|
+
"ruleId",
|
|
513
|
+
"documentPattern",
|
|
514
|
+
"daysThreshold",
|
|
515
|
+
"commitCountThreshold",
|
|
516
|
+
"evaluationMode"
|
|
517
|
+
],
|
|
518
|
+
"properties": {
|
|
519
|
+
"ruleId": {
|
|
520
|
+
"type": "string",
|
|
521
|
+
"minLength": 1
|
|
522
|
+
},
|
|
523
|
+
"documentPattern": {
|
|
524
|
+
"type": "string",
|
|
525
|
+
"minLength": 1
|
|
526
|
+
},
|
|
527
|
+
"daysThreshold": {
|
|
528
|
+
"type": "number",
|
|
529
|
+
"minimum": 0
|
|
530
|
+
},
|
|
531
|
+
"commitCountThreshold": {
|
|
532
|
+
"type": "number",
|
|
533
|
+
"minimum": 0
|
|
534
|
+
},
|
|
535
|
+
"evaluationMode": {
|
|
536
|
+
"type": "string",
|
|
537
|
+
"enum": [
|
|
538
|
+
"or",
|
|
539
|
+
"and"
|
|
540
|
+
]
|
|
541
|
+
},
|
|
542
|
+
"enabled": {
|
|
543
|
+
"type": "boolean"
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
"uniqueItems": true
|
|
548
|
+
}
|
|
549
|
+
}
|
|
501
550
|
}
|
|
502
551
|
}
|
|
503
552
|
}
|
package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json
CHANGED
|
@@ -619,6 +619,55 @@
|
|
|
619
619
|
"then": { "required": ["preset", "layers", "allowedDependencies"] }
|
|
620
620
|
}
|
|
621
621
|
]
|
|
622
|
+
},
|
|
623
|
+
"phase2Extensions": {
|
|
624
|
+
"type": "object",
|
|
625
|
+
"additionalProperties": false,
|
|
626
|
+
"properties": {
|
|
627
|
+
"initialCreationExpirationRules": {
|
|
628
|
+
"type": "array",
|
|
629
|
+
"items": {
|
|
630
|
+
"type": "object",
|
|
631
|
+
"additionalProperties": false,
|
|
632
|
+
"required": [
|
|
633
|
+
"ruleId",
|
|
634
|
+
"documentPattern",
|
|
635
|
+
"daysThreshold",
|
|
636
|
+
"commitCountThreshold",
|
|
637
|
+
"evaluationMode"
|
|
638
|
+
],
|
|
639
|
+
"properties": {
|
|
640
|
+
"ruleId": {
|
|
641
|
+
"type": "string",
|
|
642
|
+
"minLength": 1
|
|
643
|
+
},
|
|
644
|
+
"documentPattern": {
|
|
645
|
+
"type": "string",
|
|
646
|
+
"minLength": 1
|
|
647
|
+
},
|
|
648
|
+
"daysThreshold": {
|
|
649
|
+
"type": "number",
|
|
650
|
+
"minimum": 0
|
|
651
|
+
},
|
|
652
|
+
"commitCountThreshold": {
|
|
653
|
+
"type": "number",
|
|
654
|
+
"minimum": 0
|
|
655
|
+
},
|
|
656
|
+
"evaluationMode": {
|
|
657
|
+
"type": "string",
|
|
658
|
+
"enum": [
|
|
659
|
+
"or",
|
|
660
|
+
"and"
|
|
661
|
+
]
|
|
662
|
+
},
|
|
663
|
+
"enabled": {
|
|
664
|
+
"type": "boolean"
|
|
665
|
+
}
|
|
666
|
+
}
|
|
667
|
+
},
|
|
668
|
+
"uniqueItems": true
|
|
669
|
+
}
|
|
670
|
+
}
|
|
622
671
|
}
|
|
623
672
|
}
|
|
624
673
|
}
|
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
// @work-item-id WI-174
|
|
5
5
|
// @work-item-id WI-175
|
|
6
6
|
// @work-item-id WI-177
|
|
7
|
+
// @work-item-id WI-182
|
|
8
|
+
// @work-item-id WI-183
|
|
7
9
|
|
|
8
10
|
import { mkdir, readFile, writeFile, copyFile, chmod, access, lstat, readlink, symlink } from "node:fs/promises";
|
|
9
11
|
import { dirname, join } from "node:path";
|
package/scripts/harness/main.ts
CHANGED
|
@@ -221,7 +221,7 @@ Commands:
|
|
|
221
221
|
p2:check-freshness Check doc freshness (--pattern <glob>, --dry-run, --format text|json)
|
|
222
222
|
p2:validate-pointers Validate doc pointers (--include-urls, --format text|json)
|
|
223
223
|
p2:generate-e2e-template Generate E2E test template (--phase <phase>, --output <path>)
|
|
224
|
-
p2:check-initial-creation
|
|
224
|
+
p2:check-initial-creation Public compatibility detector for long-lived initial_creation:true docs (--pattern <glob>, --format text|json)
|
|
225
225
|
hook <pre-tool-use|post-tool-use|stop|session-start|user-prompt-submit> Run agent hook (reads JSON from stdin; writes JSON to stdout for session-start/user-prompt-submit)
|
|
226
226
|
pre-commit Run L2 pre-commit validators on staged files
|
|
227
227
|
commit-msg <message-file> Validate commit message trailers against staged files
|