phasegate 0.254.0 → 0.283.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.
- package/CHANGELOG.md +60 -0
- package/README.ja.md +6 -3
- package/README.md +6 -3
- package/docs/contracts/attestation-v2.schema.json +110 -0
- package/docs/guide/cli-reference.md +12 -1
- package/docs/guide/configuration.md +56 -0
- package/docs/guide/installation.md +1 -1
- package/docs/templates/ci/aidlc-gate.yml +60 -2
- package/package.json +2 -2
- package/scripts/harness/agent-integration/application/dto/open-world-obligations-context-dto.ts +30 -0
- package/scripts/harness/agent-integration/application/ports/world-obligations-query-port.ts +30 -0
- package/scripts/harness/agent-integration/application/usecases/get-open-world-obligations-context-usecase.ts +66 -0
- package/scripts/harness/agent-integration/infrastructure/adapters/harness-config-config-query-adapter.ts +30 -27
- package/scripts/harness/agent-integration/infrastructure/adapters/world-model-open-obligations-query-adapter.ts +58 -0
- package/scripts/harness/agent-integration/presentation/post-tool-use-hook.ts +29 -16
- package/scripts/harness/agent-integration/presentation/session-start-hook.ts +37 -1
- package/scripts/harness/agent-integration/presentation/stop-hook.ts +35 -26
- package/scripts/harness/agent-integration/presentation/world-obligations-session-context.ts +60 -0
- package/scripts/harness/attestation/application/dto/attestation-document.ts +17 -4
- package/scripts/harness/attestation/application/mappers/attestation-record-mapper.ts +55 -4
- package/scripts/harness/attestation/application/ports/world-snapshot-root-provider.ts +10 -0
- package/scripts/harness/attestation/application/usecases/produce-attestation-usecase.ts +33 -7
- package/scripts/harness/attestation/composition-root.ts +5 -0
- package/scripts/harness/attestation/domain/entities/attestation-record.ts +37 -2
- package/scripts/harness/attestation/index.ts +7 -1
- package/scripts/harness/attestation/presentation/handlers/attest-handler.ts +5 -2
- package/scripts/harness/config-foundation/application/mappers/validator-system-config-mapper.ts +40 -9
- package/scripts/harness/config-foundation/application/mappers/world-model-config-mapper.ts +15 -0
- package/scripts/harness/config-foundation/domain/harness-config.ts +70 -87
- package/scripts/harness/config-foundation/domain/services/preset-resolution-service.ts +80 -88
- package/scripts/harness/config-foundation/domain/value-objects/project-config.ts +34 -18
- package/scripts/harness/config-foundation/domain/value-objects/world-config.ts +198 -0
- package/scripts/harness/config-foundation/index.ts +14 -15
- package/scripts/harness/config-foundation/infrastructure/presets/minimal.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/standard.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/presets/strict.json +24 -0
- package/scripts/harness/config-foundation/infrastructure/repositories/file-system-config-repository.ts +27 -18
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v2.schema.json +84 -8
- package/scripts/harness/config-foundation/infrastructure/schemas/harness-config-v3.schema.json +84 -8
- package/scripts/harness/harness-api/domain/ports/config-query-port.ts +11 -1
- package/scripts/harness/harness-api/domain/services/command-dispatch-service.ts +125 -86
- package/scripts/harness/harness-api/domain/services/status-derivation-service.ts +31 -21
- package/scripts/harness/harness-api/domain/value-objects/ci-check-result.ts +18 -4
- package/scripts/harness/harness-api/domain/value-objects/harness-status-summary.ts +23 -8
- package/scripts/harness/harness-api/infrastructure/adapters/biome-ast-engine-lint-adapter.ts +4 -4
- package/scripts/harness/harness-api/infrastructure/adapters/harness-config-query-adapter.ts +79 -34
- package/scripts/harness/installation/application/usecases/run-install.ts +199 -51
- package/scripts/harness/installation/application/usecases/run-reconcile.ts +277 -69
- package/scripts/harness/installation/domain/deployment-manifest.ts +43 -0
- package/scripts/harness/integrations/pre-commit.ts +169 -27
- package/scripts/harness/main.ts +200 -136
- package/scripts/harness/traceability-model/application/dto/changed-design-fragment-dto.ts +31 -0
- package/scripts/harness/traceability-model/application/facades/design-change-read-facade.ts +14 -0
- package/scripts/harness/traceability-model/application/ports/staged-design-change-source-port.ts +9 -0
- package/scripts/harness/traceability-model/composition-root.ts +5 -0
- package/scripts/harness/traceability-model/index.ts +9 -0
- package/scripts/harness/traceability-model/infrastructure/adapters/git-staged-design-change-adapter.ts +155 -0
- package/scripts/harness/validator-system/application/use-cases/run-l2-validators-usecase.ts +31 -0
- package/scripts/harness/validator-system/application/use-cases/run-l3-validators-usecase.ts +57 -6
- package/scripts/harness/validator-system/composition-root.ts +25 -7
- package/scripts/harness/validator-system/domain/ports/ac-coverage-policy-port.ts +10 -1
- package/scripts/harness/validator-system/domain/ports/world-constraint-admission-policy-port.ts +28 -0
- package/scripts/harness/validator-system/domain/ports/world-constraint-rederivation-policy-port.ts +11 -0
- package/scripts/harness/validator-system/domain/services/design-change-declaration-policy.ts +75 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-admission-service.ts +78 -0
- package/scripts/harness/validator-system/domain/services/world-constraint-rederivation-service.ts +76 -0
- package/scripts/harness/validator-system/domain/value-objects/validator-id.ts +4 -0
- package/scripts/harness/validator-system/infrastructure/adapters/harness-config-validator-config-adapter.ts +126 -18
- package/scripts/harness/validator-system/infrastructure/adapters/nyquist-ac-coverage-policy-adapter.ts +49 -20
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-admission-adapter.ts +56 -0
- package/scripts/harness/validator-system/infrastructure/adapters/world-model-constraint-rederivation-adapter.ts +56 -0
- package/scripts/harness/world-model/application/dto/pinned-design-endpoint-dto.ts +19 -0
- package/scripts/harness/world-model/application/dto/world-resolved-config-input.ts +92 -27
- package/scripts/harness/world-model/application/dto/world-snapshot-root-dto.ts +8 -0
- package/scripts/harness/world-model/application/facades/pinned-design-endpoint-facade.ts +63 -0
- package/scripts/harness/world-model/application/facades/world-snapshot-root-facade.ts +19 -0
- package/scripts/harness/world-model/application/usecases/derive-world-obligations-use-case.ts +3 -1
- package/scripts/harness/world-model/composition-root.ts +62 -33
- package/scripts/harness/world-model/index.ts +11 -0
- package/scripts/harness/world-model/infrastructure/adapters/attestation-fact-extractor.ts +48 -13
- package/scripts/harness/world-model/infrastructure/adapters/file-system-world-control-repository-adapters.ts +6 -4
- package/scripts/harness/world-model/presentation/cli/world-derive-command-handler.ts +6 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @unit world-model
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
// @work-item-id WI-290
|
|
4
|
+
// @work-item-id WI-306
|
|
4
5
|
|
|
5
6
|
import type {
|
|
6
7
|
AttestationDocument,
|
|
@@ -114,13 +115,24 @@ export class AttestationFactExtractor {
|
|
|
114
115
|
|
|
115
116
|
private parseDocument(value: unknown): AttestationDocument {
|
|
116
117
|
const root = requireObject(value, "attestation");
|
|
118
|
+
const schemaVersion = requireString(root.schemaVersion, "attestation.schemaVersion");
|
|
119
|
+
const isV2 = schemaVersion === "phasegate-attestation/v2";
|
|
117
120
|
assertExactKeys(
|
|
118
121
|
root,
|
|
119
|
-
[
|
|
122
|
+
[
|
|
123
|
+
"schemaVersion",
|
|
124
|
+
"predicateType",
|
|
125
|
+
"subject",
|
|
126
|
+
"inputs",
|
|
127
|
+
"granularity",
|
|
128
|
+
"acBoundScope",
|
|
129
|
+
"metadata",
|
|
130
|
+
"signature",
|
|
131
|
+
...(isV2 ? ["worldSnapshotRoot"] : []),
|
|
132
|
+
],
|
|
120
133
|
"attestation",
|
|
121
134
|
);
|
|
122
|
-
|
|
123
|
-
if (schemaVersion !== "phasegate-attestation/v1") {
|
|
135
|
+
if (schemaVersion !== "phasegate-attestation/v1" && !isV2) {
|
|
124
136
|
throw new OwnerProjectionError(
|
|
125
137
|
"unsupported-provider-schema",
|
|
126
138
|
`unsupported attestation schema: ${schemaVersion}`,
|
|
@@ -128,14 +140,21 @@ export class AttestationFactExtractor {
|
|
|
128
140
|
);
|
|
129
141
|
}
|
|
130
142
|
const predicateType = requireString(root.predicateType, "attestation.predicateType");
|
|
143
|
+
const expectedPredicate = `https://phasegate.dev/attestation/gate-run/${isV2 ? "v2" : "v1"}`;
|
|
144
|
+
if (predicateType !== expectedPredicate) {
|
|
145
|
+
throw new OwnerProjectionError("malformed-provider-document", "attestation predicateType is inconsistent");
|
|
146
|
+
}
|
|
147
|
+
const worldSnapshotRoot = isV2 ? requireString(root.worldSnapshotRoot, "attestation.worldSnapshotRoot") : undefined;
|
|
148
|
+
if (worldSnapshotRoot !== undefined) this.assertDigest(worldSnapshotRoot, "attestation.worldSnapshotRoot");
|
|
131
149
|
|
|
132
150
|
const subject = requireObject(root.subject, "attestation.subject");
|
|
133
151
|
assertExactKeys(subject, ["command", "gateResult", "validatorSet"], "attestation.subject");
|
|
134
152
|
const command = requireString(subject.command, "attestation.subject.command");
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
153
|
+
const gateResultRaw = requireString(subject.gateResult, "attestation.subject.gateResult");
|
|
154
|
+
if (gateResultRaw !== "pass" && gateResultRaw !== "fail") {
|
|
137
155
|
throw new OwnerProjectionError("malformed-provider-document", "attestation gateResult is invalid");
|
|
138
156
|
}
|
|
157
|
+
const gateResult: "pass" | "fail" = gateResultRaw;
|
|
139
158
|
const validatorSet = requireArray(subject.validatorSet, "attestation.subject.validatorSet").map((raw, index) => {
|
|
140
159
|
const field = `attestation.subject.validatorSet[${index}]`;
|
|
141
160
|
const outcome = requireObject(raw, field);
|
|
@@ -174,10 +193,11 @@ export class AttestationFactExtractor {
|
|
|
174
193
|
["validator", "level", "claim", "knownLimitations"],
|
|
175
194
|
"attestation.granularity.traceability",
|
|
176
195
|
);
|
|
177
|
-
const
|
|
178
|
-
if (
|
|
196
|
+
const levelRaw = requireString(traceability.level, "attestation.granularity.traceability.level");
|
|
197
|
+
if (levelRaw !== "file" && levelRaw !== "ac") {
|
|
179
198
|
throw new OwnerProjectionError("malformed-provider-document", "attestation granularity level is invalid");
|
|
180
199
|
}
|
|
200
|
+
const level: "file" | "ac" = levelRaw;
|
|
181
201
|
const knownLimitations = requireArray(
|
|
182
202
|
traceability.knownLimitations,
|
|
183
203
|
"attestation.granularity.traceability.knownLimitations",
|
|
@@ -193,21 +213,20 @@ export class AttestationFactExtractor {
|
|
|
193
213
|
|
|
194
214
|
const signature = requireObject(root.signature, "attestation.signature");
|
|
195
215
|
assertExactKeys(signature, ["mode", "attestationDigest", "algorithm", "keyId", "value"], "attestation.signature");
|
|
196
|
-
const
|
|
197
|
-
if (
|
|
216
|
+
const modeRaw = requireString(signature.mode, "attestation.signature.mode");
|
|
217
|
+
if (modeRaw !== "unsigned-poc" && modeRaw !== "signed") {
|
|
198
218
|
throw new OwnerProjectionError("malformed-provider-document", "attestation signature mode is invalid");
|
|
199
219
|
}
|
|
220
|
+
const mode: "unsigned-poc" | "signed" = modeRaw;
|
|
200
221
|
const attestationDigest = requireString(signature.attestationDigest, "attestation.signature.attestationDigest");
|
|
201
222
|
this.assertDigest(attestationDigest, "attestation.signature.attestationDigest");
|
|
202
223
|
const nullableString = (candidate: unknown, field: string): string | null =>
|
|
203
224
|
candidate === null ? null : requireString(candidate, field);
|
|
204
225
|
|
|
205
|
-
|
|
206
|
-
schemaVersion,
|
|
207
|
-
predicateType,
|
|
226
|
+
const common = {
|
|
208
227
|
subject: { command, gateResult, validatorSet },
|
|
209
228
|
inputs: {
|
|
210
|
-
digestAlgorithm: "sha256",
|
|
229
|
+
digestAlgorithm: "sha256" as const,
|
|
211
230
|
sources,
|
|
212
231
|
inputDigest,
|
|
213
232
|
},
|
|
@@ -233,6 +252,22 @@ export class AttestationFactExtractor {
|
|
|
233
252
|
value: nullableString(signature.value, "attestation.signature.value"),
|
|
234
253
|
},
|
|
235
254
|
};
|
|
255
|
+
if (isV2) {
|
|
256
|
+
if (worldSnapshotRoot === undefined) {
|
|
257
|
+
throw new OwnerProjectionError("malformed-provider-document", "attestation v2 root is missing");
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
...common,
|
|
261
|
+
schemaVersion: "phasegate-attestation/v2",
|
|
262
|
+
predicateType: "https://phasegate.dev/attestation/gate-run/v2",
|
|
263
|
+
worldSnapshotRoot,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
...common,
|
|
268
|
+
schemaVersion: "phasegate-attestation/v1",
|
|
269
|
+
predicateType: "https://phasegate.dev/attestation/gate-run/v1",
|
|
270
|
+
};
|
|
236
271
|
}
|
|
237
272
|
|
|
238
273
|
private project(document: AttestationDocument, verification: VerifyAttestationOutput): CanonicalJsonObject {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// @unit world-model
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
// @work-item-id WI-294
|
|
4
|
+
// @work-item-id WI-300
|
|
4
5
|
|
|
5
6
|
import { readFile, rename, rm, writeFile } from "node:fs/promises";
|
|
6
7
|
import path from "node:path";
|
|
@@ -40,6 +41,7 @@ let temporarySequence = 0;
|
|
|
40
41
|
|
|
41
42
|
interface RepositoryOptions {
|
|
42
43
|
readonly rootDir: string;
|
|
44
|
+
readonly fileName?: string;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
47
|
interface DeclarationSpec<T> {
|
|
@@ -238,7 +240,7 @@ export class FileSystemConstraintDeclarationRepositoryAdapter implements Constra
|
|
|
238
240
|
private readonly repository: FileSystemWorldControlRepository<ConstraintDeclarationSet>;
|
|
239
241
|
|
|
240
242
|
constructor(options: RepositoryOptions) {
|
|
241
|
-
const fileName = "phasegate.world-constraints.json";
|
|
243
|
+
const fileName = options.fileName ?? "phasegate.world-constraints.json";
|
|
242
244
|
const artifactId = WorldNodeId.artifact(
|
|
243
245
|
ArtifactKind.externalDeclaration(),
|
|
244
246
|
CorpusRole.external(),
|
|
@@ -268,7 +270,7 @@ export class FileSystemAdoptionBaselineRepositoryAdapter implements AdoptionBase
|
|
|
268
270
|
|
|
269
271
|
constructor(options: RepositoryOptions) {
|
|
270
272
|
this.repository = new FileSystemWorldControlRepository(options, {
|
|
271
|
-
fileName: "phasegate.world-baseline.json",
|
|
273
|
+
fileName: options.fileName ?? "phasegate.world-baseline.json",
|
|
272
274
|
schemaFileName: "world-baseline.schema.json",
|
|
273
275
|
schemaVersion: "phasegate-world-adoption-baseline/v1",
|
|
274
276
|
emptyValue: null,
|
|
@@ -290,7 +292,7 @@ export class FileSystemWaiverDeclarationRepositoryAdapter implements WaiverDecla
|
|
|
290
292
|
|
|
291
293
|
constructor(options: RepositoryOptions) {
|
|
292
294
|
this.repository = new FileSystemWorldControlRepository(options, {
|
|
293
|
-
fileName: "phasegate.world-waivers.json",
|
|
295
|
+
fileName: options.fileName ?? "phasegate.world-waivers.json",
|
|
294
296
|
schemaFileName: "world-waivers.schema.json",
|
|
295
297
|
schemaVersion: "phasegate-world-waivers/v1",
|
|
296
298
|
emptyValue: Object.freeze([]),
|
|
@@ -312,7 +314,7 @@ export class FileSystemSemanticDebtRepositoryAdapter implements SemanticDebtRepo
|
|
|
312
314
|
|
|
313
315
|
constructor(options: RepositoryOptions) {
|
|
314
316
|
this.repository = new FileSystemWorldControlRepository(options, {
|
|
315
|
-
fileName: "phasegate.world-debts.json",
|
|
317
|
+
fileName: options.fileName ?? "phasegate.world-debts.json",
|
|
316
318
|
schemaFileName: "world-debts.schema.json",
|
|
317
319
|
schemaVersion: "phasegate-world-debts/v1",
|
|
318
320
|
emptyValue: Object.freeze([]),
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
// @unit world-model
|
|
2
2
|
// @layer presentation
|
|
3
3
|
// @work-item-id WI-296
|
|
4
|
+
// @work-item-id WI-300
|
|
4
5
|
|
|
5
6
|
import type { DeriveWorldObligationsUseCase } from "../../application/usecases/derive-world-obligations-use-case.js";
|
|
6
7
|
import { PathKey } from "../../domain/value-objects/path-key.js";
|
|
7
8
|
import { envelope, parseFormat, type WorldCommandResult, type WorldOutputFormat } from "./world-command-support.js";
|
|
8
9
|
|
|
9
10
|
export class WorldDeriveCommandHandler {
|
|
10
|
-
constructor(
|
|
11
|
+
constructor(
|
|
12
|
+
private readonly useCase: Pick<DeriveWorldObligationsUseCase, "execute">,
|
|
13
|
+
private readonly defaultReportPath = ".harness/world-obligations.json",
|
|
14
|
+
) {}
|
|
11
15
|
|
|
12
16
|
static fromFailure(error: unknown): WorldDeriveCommandHandler {
|
|
13
17
|
return new WorldDeriveCommandHandler({
|
|
@@ -57,7 +61,7 @@ export class WorldDeriveCommandHandler {
|
|
|
57
61
|
const data = {
|
|
58
62
|
report,
|
|
59
63
|
persistence: result.result.persistence,
|
|
60
|
-
writtenPath: writeReport ? (reportPath ??
|
|
64
|
+
writtenPath: writeReport ? (reportPath ?? this.defaultReportPath) : null,
|
|
61
65
|
};
|
|
62
66
|
if (formatted.format === "json") {
|
|
63
67
|
return {
|