@ai-sdlc/orchestrator 0.9.0 → 0.13.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/dist/__test-helpers/git-env.d.ts +40 -0
- package/dist/__test-helpers/git-env.js +73 -0
- package/dist/adapters.d.ts +42 -3
- package/dist/adapters.js +133 -3
- package/dist/admission-composite.d.ts +134 -1
- package/dist/admission-composite.js +170 -6
- package/dist/admission-enrichment.d.ts +12 -3
- package/dist/admission-enrichment.js +71 -10
- package/dist/admission-hc.d.ts +20 -1
- package/dist/admission-hc.js +12 -1
- package/dist/admission-score.d.ts +44 -0
- package/dist/admission-score.js +11 -2
- package/dist/backlog-adapter.d.ts +45 -0
- package/dist/backlog-adapter.js +145 -1
- package/dist/calibration.d.ts +81 -0
- package/dist/calibration.js +76 -0
- package/dist/cli/commands/git-remote.d.ts +25 -0
- package/dist/cli/commands/git-remote.js +80 -1
- package/dist/cli/commands/init-features.d.ts +507 -0
- package/dist/cli/commands/init-features.js +1100 -0
- package/dist/cli/commands/init-templates.d.ts +301 -0
- package/dist/cli/commands/init-templates.js +1341 -0
- package/dist/cli/commands/init.d.ts +67 -0
- package/dist/cli/commands/init.js +301 -2
- package/dist/cli/commands/run.js +9 -1
- package/dist/cli/index.d.ts +11 -0
- package/dist/cli/index.js +42 -8
- package/dist/compliance/composer.d.ts +79 -0
- package/dist/compliance/composer.js +258 -0
- package/dist/compliance/errors.d.ts +64 -0
- package/dist/compliance/errors.js +85 -0
- package/dist/compliance/loader.d.ts +52 -0
- package/dist/compliance/loader.js +124 -0
- package/dist/compliance/types.d.ts +184 -0
- package/dist/compliance/types.js +41 -0
- package/dist/compliance-clearance.d.ts +269 -0
- package/dist/compliance-clearance.js +269 -0
- package/dist/config.js +17 -0
- package/dist/cost-tracker.d.ts +22 -0
- package/dist/cost-tracker.js +41 -0
- package/dist/database/adapters/external.js +5 -1
- package/dist/design-authority.d.ts +13 -0
- package/dist/design-authority.js +13 -0
- package/dist/embedding/adapters/openai-text-embedding-3-small.d.ts +71 -0
- package/dist/embedding/adapters/openai-text-embedding-3-small.js +190 -0
- package/dist/embedding/consumers/tessellation-drift.d.ts +74 -0
- package/dist/embedding/consumers/tessellation-drift.js +76 -0
- package/dist/embedding/cross-provider.d.ts +78 -0
- package/dist/embedding/cross-provider.js +75 -0
- package/dist/embedding/deprecation.d.ts +151 -0
- package/dist/embedding/deprecation.js +229 -0
- package/dist/embedding/errors.d.ts +90 -0
- package/dist/embedding/errors.js +150 -0
- package/dist/embedding/index.d.ts +29 -0
- package/dist/embedding/index.js +24 -0
- package/dist/embedding/pipeline-load.d.ts +146 -0
- package/dist/embedding/pipeline-load.js +178 -0
- package/dist/embedding/registry.d.ts +45 -0
- package/dist/embedding/registry.js +61 -0
- package/dist/embedding/stale-vector.d.ts +110 -0
- package/dist/embedding/stale-vector.js +92 -0
- package/dist/embedding/storage/index.d.ts +51 -0
- package/dist/embedding/storage/index.js +43 -0
- package/dist/embedding/storage/jsonl-backend.d.ts +150 -0
- package/dist/embedding/storage/jsonl-backend.js +332 -0
- package/dist/embedding/storage/types.d.ts +135 -0
- package/dist/embedding/storage/types.js +13 -0
- package/dist/embedding/types.d.ts +180 -0
- package/dist/embedding/types.js +10 -0
- package/dist/execute.d.ts +29 -2
- package/dist/execute.js +179 -35
- package/dist/index.d.ts +14 -2
- package/dist/index.js +19 -2
- package/dist/journey/inheritance-validator.d.ts +396 -0
- package/dist/journey/inheritance-validator.js +370 -0
- package/dist/journey/state-id-drift-rule.d.ts +137 -0
- package/dist/journey/state-id-drift-rule.js +245 -0
- package/dist/journey-sa2-router.d.ts +395 -0
- package/dist/journey-sa2-router.js +308 -0
- package/dist/models/classifier.d.ts +3 -1
- package/dist/models/classifier.js +61 -5
- package/dist/pillar-breakdown.d.ts +23 -1
- package/dist/pillar-breakdown.js +9 -0
- package/dist/runners/review-agent.js +6 -2
- package/dist/runners/runner-registry.d.ts +36 -0
- package/dist/runners/runner-registry.js +90 -0
- package/dist/runtime/attestations.d.ts +663 -11
- package/dist/runtime/attestations.js +971 -24
- package/dist/runtime/index.d.ts +1 -1
- package/dist/runtime/index.js +1 -1
- package/dist/runtime/parallelism-flag.d.ts +21 -3
- package/dist/runtime/parallelism-flag.js +27 -6
- package/dist/runtime/port-allocator.d.ts +11 -0
- package/dist/runtime/port-allocator.js +30 -0
- package/dist/sa-scoring/layer3-llm.js +6 -1
- package/dist/sa-scoring/revision-proposal-config.d.ts +178 -0
- package/dist/sa-scoring/revision-proposal-config.js +198 -0
- package/dist/sa-scoring/revision-proposal.d.ts +285 -0
- package/dist/sa-scoring/revision-proposal.js +417 -0
- package/dist/signal-ingestion/adapters/community-thread.d.ts +43 -0
- package/dist/signal-ingestion/adapters/community-thread.js +55 -0
- package/dist/signal-ingestion/adapters/in-app-feedback.d.ts +67 -0
- package/dist/signal-ingestion/adapters/in-app-feedback.js +51 -0
- package/dist/signal-ingestion/adapters/manual.d.ts +78 -0
- package/dist/signal-ingestion/adapters/manual.js +112 -0
- package/dist/signal-ingestion/adapters/support-ticket.d.ts +47 -0
- package/dist/signal-ingestion/adapters/support-ticket.js +51 -0
- package/dist/signal-ingestion/classifier.d.ts +205 -0
- package/dist/signal-ingestion/classifier.js +494 -0
- package/dist/signal-ingestion/clustering-types.d.ts +36 -0
- package/dist/signal-ingestion/clustering-types.js +14 -0
- package/dist/signal-ingestion/clustering.d.ts +200 -0
- package/dist/signal-ingestion/clustering.js +413 -0
- package/dist/signal-ingestion/config.d.ts +351 -0
- package/dist/signal-ingestion/config.js +587 -0
- package/dist/signal-ingestion/d1.d.ts +252 -0
- package/dist/signal-ingestion/d1.js +235 -0
- package/dist/signal-ingestion/errors.d.ts +73 -0
- package/dist/signal-ingestion/errors.js +108 -0
- package/dist/signal-ingestion/governance-events.d.ts +181 -0
- package/dist/signal-ingestion/governance-events.js +189 -0
- package/dist/signal-ingestion/index.d.ts +35 -0
- package/dist/signal-ingestion/index.js +53 -0
- package/dist/signal-ingestion/manual-share-metric.d.ts +93 -0
- package/dist/signal-ingestion/manual-share-metric.js +106 -0
- package/dist/signal-ingestion/registry.d.ts +40 -0
- package/dist/signal-ingestion/registry.js +137 -0
- package/dist/signal-ingestion/residency.d.ts +227 -0
- package/dist/signal-ingestion/residency.js +238 -0
- package/dist/signal-ingestion/significance.d.ts +554 -0
- package/dist/signal-ingestion/significance.js +555 -0
- package/dist/signal-ingestion/types.d.ts +191 -0
- package/dist/signal-ingestion/types.js +8 -0
- package/dist/substrate/drift-composition.d.ts +270 -0
- package/dist/substrate/drift-composition.js +306 -0
- package/dist/substrate/drift-tui-surface.d.ts +61 -0
- package/dist/substrate/drift-tui-surface.js +102 -0
- package/dist/substrate/identity-class.d.ts +176 -0
- package/dist/substrate/identity-class.js +201 -0
- package/dist/tessellation/cross-soul-provenance-rule.d.ts +133 -0
- package/dist/tessellation/cross-soul-provenance-rule.js +171 -0
- package/dist/tessellation/inter-soul-embedding-distance-rule.d.ts +61 -0
- package/dist/tessellation/inter-soul-embedding-distance-rule.js +67 -0
- package/dist/tessellation/rule-registry.d.ts +269 -0
- package/dist/tessellation/rule-registry.js +92 -0
- package/dist/tessellation/soul-slug-ast-scan-rule.d.ts +90 -0
- package/dist/tessellation/soul-slug-ast-scan-rule.js +158 -0
- package/dist/tessellation-admission.d.ts +162 -0
- package/dist/tessellation-admission.js +146 -0
- package/dist/tessellation-drift.d.ts +246 -0
- package/dist/tessellation-drift.js +250 -0
- package/dist/validate-config.js +13 -0
- package/dist/validate-issue.js +2 -2
- package/dist/variant/cardinality-activation.d.ts +126 -0
- package/dist/variant/cardinality-activation.js +101 -0
- package/dist/variant/deprecation-lifecycle.d.ts +184 -0
- package/dist/variant/deprecation-lifecycle.js +208 -0
- package/dist/variant/drift-extension.d.ts +136 -0
- package/dist/variant/drift-extension.js +164 -0
- package/dist/variant/engineering-review.d.ts +185 -0
- package/dist/variant/engineering-review.js +142 -0
- package/dist/variant/index.d.ts +32 -0
- package/dist/variant/index.js +32 -0
- package/dist/variant/inheritance-validator.d.ts +165 -0
- package/dist/variant/inheritance-validator.js +139 -0
- package/dist/variant/internal-adopter/index.d.ts +11 -0
- package/dist/variant/internal-adopter/index.js +10 -0
- package/dist/variant/internal-adopter/products.d.ts +156 -0
- package/dist/variant/internal-adopter/products.js +366 -0
- package/dist/variant-admission.d.ts +316 -0
- package/dist/variant-admission.js +247 -0
- package/package.json +11 -8
package/dist/runtime/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { slugifyBranch, worktreePath, verifyOwnership, assertOwnership, isExisti
|
|
|
3
3
|
export { WorktreePoolManager, WorktreePoolError, DEFAULT_POOL_ROOT, DEFAULT_STALE_THRESHOLD_DAYS, type WorktreePoolSpec, type WorktreePoolManagerDeps, type AllocateOptions, type WorktreeHandle, } from './worktree-pool.js';
|
|
4
4
|
export { readParallelismMode, isParallelismEnabled, FLAG_NAME as PARALLELISM_FLAG, type ParallelismMode, } from './parallelism-flag.js';
|
|
5
5
|
export { cleanGitEnv, gitExecFile } from './git-env.js';
|
|
6
|
-
export { ACCEPTED_SCHEMA_VERSIONS, DSSE_PAYLOAD_TYPE, buildPredicate, generateSigningKeyPair, paeEncode, sha1Hex, sha256Hex, signAttestation, validateTrustedReviewers, verifyAttestation, type AttestationPredicate, type DsseEnvelope, type DsseSignature, type ReviewerEntry, type SchemaVersion, type SubjectDigest, type TrustedReviewer, type VerifyResult, } from './attestations.js';
|
|
6
|
+
export { ACCEPTED_SCHEMA_VERSIONS, ATTESTATION_ENVELOPE_PATH_PATTERN, CONTENTHASH_SHARED_CHURN_FILES, CONTENTHASHV4_IGNORE_FILES, DSSE_PAYLOAD_TYPE, INDEPENDENCE_REQUIRED_ROLES, REQUIRED_REVIEWER_AGENT_IDS, REVIEWER_ROLE_EQUIVALENCES, buildPredicate, collectChangedFileDeltaEntries, collectChangedFileEntries, collectChangedFileEntriesForV5, computeContentHash, computeContentHashV3, computeContentHashV4, computeContentHashV5, generateSigningKeyPair, isAttestationEnvelopePath, isIgnoredForContentHash, paeEncode, projectDeltaEntriesToHeadEntries, sha1Hex, sha256Hex, signAttestation, validatePredicateShape, validateTrustedReviewers, verifyAttestation, type AttestationPredicate, type BuildPredicateInputs, type ChangedFileDeltaEntry, type ChangedFileEntry, type ChangedFileHeadEntry, type ChangedFileV5Entry, type CollectChangedFileEntriesOptions, type DsseEnvelope, type DsseSignature, type ReviewerEntry, type SchemaVersion, type SubjectDigest, type TrustedReviewer, type V5CollectResult, type VerifyOptions, type VerifyResult, } from './attestations.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/runtime/index.js
CHANGED
|
@@ -3,5 +3,5 @@ export { slugifyBranch, worktreePath, verifyOwnership, assertOwnership, isExisti
|
|
|
3
3
|
export { WorktreePoolManager, WorktreePoolError, DEFAULT_POOL_ROOT, DEFAULT_STALE_THRESHOLD_DAYS, } from './worktree-pool.js';
|
|
4
4
|
export { readParallelismMode, isParallelismEnabled, FLAG_NAME as PARALLELISM_FLAG, } from './parallelism-flag.js';
|
|
5
5
|
export { cleanGitEnv, gitExecFile } from './git-env.js';
|
|
6
|
-
export { ACCEPTED_SCHEMA_VERSIONS, DSSE_PAYLOAD_TYPE, buildPredicate, generateSigningKeyPair, paeEncode, sha1Hex, sha256Hex, signAttestation, validateTrustedReviewers, verifyAttestation, } from './attestations.js';
|
|
6
|
+
export { ACCEPTED_SCHEMA_VERSIONS, ATTESTATION_ENVELOPE_PATH_PATTERN, CONTENTHASH_SHARED_CHURN_FILES, CONTENTHASHV4_IGNORE_FILES, DSSE_PAYLOAD_TYPE, INDEPENDENCE_REQUIRED_ROLES, REQUIRED_REVIEWER_AGENT_IDS, REVIEWER_ROLE_EQUIVALENCES, buildPredicate, collectChangedFileDeltaEntries, collectChangedFileEntries, collectChangedFileEntriesForV5, computeContentHash, computeContentHashV3, computeContentHashV4, computeContentHashV5, generateSigningKeyPair, isAttestationEnvelopePath, isIgnoredForContentHash, paeEncode, projectDeltaEntriesToHeadEntries, sha1Hex, sha256Hex, signAttestation, validatePredicateShape, validateTrustedReviewers, verifyAttestation, } from './attestations.js';
|
|
7
7
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,7 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Feature-flag gate for RFC-0010 parallelism.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Feature-flag gate for RFC-0010 parallelism. Phases 1-4 shipped behind
|
|
3
|
+
* AI_SDLC_PARALLELISM=experimental; Phase 5 (hardening) added the runbook,
|
|
4
|
+
* chaos plan, and stuck-heartbeat detection. Per maintainer directive
|
|
5
|
+
* 2026-05-01 (AISDLC-116), the calendar-based 1-week soak gate from RFC-0010
|
|
6
|
+
* Phase 5 was dropped in favor of substantive readiness — pre-flight scan
|
|
7
|
+
* of orchestrator/_events.jsonl + recent commit history showed zero
|
|
8
|
+
* parallelism-related incidents — and the flag now defaults to 'on'.
|
|
9
|
+
*
|
|
10
|
+
* Backwards-compat envelope (preserved on purpose):
|
|
11
|
+
* - unset → 'on' (new default)
|
|
12
|
+
* - 'on' | 'true' | '1' → 'on'
|
|
13
|
+
* - 'experimental' → 'experimental' (still honored for
|
|
14
|
+
* callers pinning the
|
|
15
|
+
* pre-promotion mode)
|
|
16
|
+
* - 'off' | 'disabled' |
|
|
17
|
+
* 'false' | '0' → 'off' (explicit opt-out)
|
|
18
|
+
* - any other string → 'on' (fail-on rather than fail-off
|
|
19
|
+
* now that 'on' is the default;
|
|
20
|
+
* prevents typos like
|
|
21
|
+
* 'enable' from silently
|
|
22
|
+
* disabling parallelism)
|
|
5
23
|
*/
|
|
6
24
|
export declare const FLAG_NAME = "AI_SDLC_PARALLELISM";
|
|
7
25
|
export type ParallelismMode = 'off' | 'experimental' | 'on';
|
|
@@ -1,16 +1,37 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Feature-flag gate for RFC-0010 parallelism.
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Feature-flag gate for RFC-0010 parallelism. Phases 1-4 shipped behind
|
|
3
|
+
* AI_SDLC_PARALLELISM=experimental; Phase 5 (hardening) added the runbook,
|
|
4
|
+
* chaos plan, and stuck-heartbeat detection. Per maintainer directive
|
|
5
|
+
* 2026-05-01 (AISDLC-116), the calendar-based 1-week soak gate from RFC-0010
|
|
6
|
+
* Phase 5 was dropped in favor of substantive readiness — pre-flight scan
|
|
7
|
+
* of orchestrator/_events.jsonl + recent commit history showed zero
|
|
8
|
+
* parallelism-related incidents — and the flag now defaults to 'on'.
|
|
9
|
+
*
|
|
10
|
+
* Backwards-compat envelope (preserved on purpose):
|
|
11
|
+
* - unset → 'on' (new default)
|
|
12
|
+
* - 'on' | 'true' | '1' → 'on'
|
|
13
|
+
* - 'experimental' → 'experimental' (still honored for
|
|
14
|
+
* callers pinning the
|
|
15
|
+
* pre-promotion mode)
|
|
16
|
+
* - 'off' | 'disabled' |
|
|
17
|
+
* 'false' | '0' → 'off' (explicit opt-out)
|
|
18
|
+
* - any other string → 'on' (fail-on rather than fail-off
|
|
19
|
+
* now that 'on' is the default;
|
|
20
|
+
* prevents typos like
|
|
21
|
+
* 'enable' from silently
|
|
22
|
+
* disabling parallelism)
|
|
5
23
|
*/
|
|
6
24
|
export const FLAG_NAME = 'AI_SDLC_PARALLELISM';
|
|
7
25
|
export function readParallelismMode(env = process.env) {
|
|
8
26
|
const raw = env[FLAG_NAME]?.trim().toLowerCase();
|
|
27
|
+
if (raw === undefined || raw === '')
|
|
28
|
+
return 'on';
|
|
9
29
|
if (raw === 'experimental')
|
|
10
30
|
return 'experimental';
|
|
11
|
-
if (raw === '
|
|
12
|
-
return '
|
|
13
|
-
|
|
31
|
+
if (raw === 'off' || raw === 'disabled' || raw === 'false' || raw === '0')
|
|
32
|
+
return 'off';
|
|
33
|
+
// 'on' / 'true' / '1' / any other value → 'on' (default-on, fail-on)
|
|
34
|
+
return 'on';
|
|
14
35
|
}
|
|
15
36
|
export function isParallelismEnabled(env) {
|
|
16
37
|
return readParallelismMode(env) !== 'off';
|
|
@@ -14,6 +14,17 @@ export declare class PortAllocationError extends Error {
|
|
|
14
14
|
readonly attemptedPorts: number[];
|
|
15
15
|
constructor(message: string, worktreePath: string, attemptedPorts: number[]);
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* Derive a deterministic port for `worktreePath` by hashing its absolute form with MD5
|
|
19
|
+
* and mapping the first two bytes into [basePort + PORT_RANGE_OFFSET_MIN,
|
|
20
|
+
* basePort + PORT_RANGE_OFFSET_MAX].
|
|
21
|
+
*
|
|
22
|
+
* **Collision risk**: the output space is only 900 ports wide. When called with multiple
|
|
23
|
+
* independent (e.g. mkdtemp-generated) paths, two or more paths may map to the same port.
|
|
24
|
+
* For n=3 paths the birthday probability is ~0.33%. Integration tests that need to assert
|
|
25
|
+
* port distinctness MUST use pre-chosen, manually-verified paths rather than random
|
|
26
|
+
* temporaries — see the module-level JSDoc for the recommended assertion pattern.
|
|
27
|
+
*/
|
|
17
28
|
export declare function deterministicPort(worktreePath: string, basePort?: number): number;
|
|
18
29
|
export declare function allocatePort(worktreePath: string, options?: AllocatePortOptions): Promise<number>;
|
|
19
30
|
export declare function allocateContiguousPorts(worktreePath: string, options: AllocateContiguousOptions): Promise<number[]>;
|
|
@@ -1,3 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deterministic port allocator for git worktrees.
|
|
3
|
+
*
|
|
4
|
+
* `deterministicPort` maps an absolute worktree path to a port number in a fixed
|
|
5
|
+
* 900-port range (DEFAULT_BASE_PORT + PORT_RANGE_OFFSET_MIN … PORT_RANGE_OFFSET_MAX)
|
|
6
|
+
* by hashing the path with MD5 and taking the first two bytes modulo the range span.
|
|
7
|
+
*
|
|
8
|
+
* **Hash-collision caveat**: the 900-port range is finite. When multiple worktree paths
|
|
9
|
+
* are fed through `deterministicPort` in a single test, birthday-paradox collisions are
|
|
10
|
+
* possible. For n=3 paths the probability is roughly (n*(n-1)/2) / span ≈ 0.33%. Over
|
|
11
|
+
* thousands of CI runs this causes spurious "distinct ports" assertion failures.
|
|
12
|
+
*
|
|
13
|
+
* **Integration-test guidance**: do NOT assert `new Set(ports).size === n` unless the
|
|
14
|
+
* test controls the exact path strings and has pre-verified they hash to distinct values.
|
|
15
|
+
* Instead assert:
|
|
16
|
+
* - each port is in [DEFAULT_BASE_PORT + PORT_RANGE_OFFSET_MIN, DEFAULT_BASE_PORT + PORT_RANGE_OFFSET_MAX]
|
|
17
|
+
* - calling allocatePort twice for the same path returns the same value (idempotency)
|
|
18
|
+
* - ports[i] === deterministicPort(h.path) (the core deterministic-port property)
|
|
19
|
+
*/
|
|
1
20
|
import { createHash } from 'node:crypto';
|
|
2
21
|
import { resolve } from 'node:path';
|
|
3
22
|
import { createServer } from 'node:net';
|
|
@@ -16,6 +35,17 @@ export class PortAllocationError extends Error {
|
|
|
16
35
|
this.name = 'PortAllocationError';
|
|
17
36
|
}
|
|
18
37
|
}
|
|
38
|
+
/**
|
|
39
|
+
* Derive a deterministic port for `worktreePath` by hashing its absolute form with MD5
|
|
40
|
+
* and mapping the first two bytes into [basePort + PORT_RANGE_OFFSET_MIN,
|
|
41
|
+
* basePort + PORT_RANGE_OFFSET_MAX].
|
|
42
|
+
*
|
|
43
|
+
* **Collision risk**: the output space is only 900 ports wide. When called with multiple
|
|
44
|
+
* independent (e.g. mkdtemp-generated) paths, two or more paths may map to the same port.
|
|
45
|
+
* For n=3 paths the birthday probability is ~0.33%. Integration tests that need to assert
|
|
46
|
+
* port distinctness MUST use pre-chosen, manually-verified paths rather than random
|
|
47
|
+
* temporaries — see the module-level JSDoc for the recommended assertion pattern.
|
|
48
|
+
*/
|
|
19
49
|
export function deterministicPort(worktreePath, basePort = DEFAULT_BASE_PORT) {
|
|
20
50
|
const absolute = resolve(worktreePath);
|
|
21
51
|
const digest = createHash('md5').update(absolute).digest();
|
|
@@ -180,7 +180,12 @@ export function buildSa2Prompt(ctx) {
|
|
|
180
180
|
}
|
|
181
181
|
/** Extract the first JSON object from a raw LLM reply. */
|
|
182
182
|
export function extractJson(raw) {
|
|
183
|
-
|
|
183
|
+
// Drop the leading optional-whitespace group entirely: any `[ \t]*`/`\s*`
|
|
184
|
+
// before the lazy `[\s\S]*?` capture overlaps it (both match space/tab),
|
|
185
|
+
// which is the polynomial-backtracking source (CodeQL js/polynomial-redos).
|
|
186
|
+
// The bounded `\n?` (0-or-1, not a `*`) is safe, and `.trim()` below absorbs
|
|
187
|
+
// any residual leading whitespace the capture picks up.
|
|
188
|
+
const fenced = raw.match(/```(?:json)?\n?([\s\S]*?)```/i);
|
|
184
189
|
const candidate = fenced ? fenced[1] : raw;
|
|
185
190
|
try {
|
|
186
191
|
return JSON.parse(candidate.trim());
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-org calibration.yaml configuration for RFC-0031 DIDRevisionProposal
|
|
3
|
+
* mechanism (Refit AISDLC-310).
|
|
4
|
+
*
|
|
5
|
+
* Exposes OQ-12.1 (confidence thresholds) and OQ-12.5 (rejection weights +
|
|
6
|
+
* penalty floor) as per-org configurable values. Defaults match the values
|
|
7
|
+
* shipped by AISDLC-271 / PR #476 and operator-affirmed during the 2026-05-16
|
|
8
|
+
* audit (RFC-0031 §12.1 + §12.5 resolutions).
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* 1. Load the `.ai-sdlc/calibration.yaml` file.
|
|
12
|
+
* 2. Call `parseRevisionProposalCalibrationYaml(content)` — validates +
|
|
13
|
+
* returns a fully-resolved config with all defaults filled in.
|
|
14
|
+
* 3. Pass the resolved config to `computeConfidence()`,
|
|
15
|
+
* `recordRejection()`, and `computeRejectionPrecedentFactor()`.
|
|
16
|
+
*
|
|
17
|
+
* Validation rules (enforced at load time):
|
|
18
|
+
* - `highSampleSize > lowSampleSize > 0`
|
|
19
|
+
* - All weights in `[0, 1]`
|
|
20
|
+
* - `confidencePenaltyFloor` in `[0, 1]`
|
|
21
|
+
*/
|
|
22
|
+
/** Minimum total signals (dismiss + escalate + drift) for HIGH confidence. */
|
|
23
|
+
export declare const DEFAULT_CONFIDENCE_HIGH_SAMPLE_SIZE = 20;
|
|
24
|
+
/** Below this total signal count the proposal is LOW confidence. */
|
|
25
|
+
export declare const DEFAULT_CONFIDENCE_LOW_SAMPLE_SIZE = 5;
|
|
26
|
+
/** Rejection precedent weight applied when the rejected proposal had HIGH confidence. */
|
|
27
|
+
export declare const DEFAULT_REJECTION_WEIGHT_HIGH = 0.8;
|
|
28
|
+
/** Rejection precedent weight applied when the rejected proposal had MEDIUM confidence. */
|
|
29
|
+
export declare const DEFAULT_REJECTION_WEIGHT_MEDIUM = 0.5;
|
|
30
|
+
/** Rejection precedent weight applied when the rejected proposal had LOW confidence. */
|
|
31
|
+
export declare const DEFAULT_REJECTION_WEIGHT_LOW = 0.2;
|
|
32
|
+
/**
|
|
33
|
+
* Minimum value for the rejection precedent factor.
|
|
34
|
+
* 0.2 = at most 80% suppression of future proposal confidence.
|
|
35
|
+
*/
|
|
36
|
+
export declare const DEFAULT_CONFIDENCE_PENALTY_FLOOR = 0.2;
|
|
37
|
+
/**
|
|
38
|
+
* Confidence threshold configuration (OQ-12.1).
|
|
39
|
+
*
|
|
40
|
+
* Sample size = `dismissSignals + escalateSignals + driftEvents`.
|
|
41
|
+
*/
|
|
42
|
+
export interface ConfidenceThresholdsConfig {
|
|
43
|
+
/**
|
|
44
|
+
* Total signal count ≥ this value contributes toward HIGH confidence
|
|
45
|
+
* (alongside non-ambiguous classification and `evolving` identityClass).
|
|
46
|
+
*
|
|
47
|
+
* @default 20
|
|
48
|
+
*/
|
|
49
|
+
highSampleSize: number;
|
|
50
|
+
/**
|
|
51
|
+
* Total signal count < this value forces LOW confidence.
|
|
52
|
+
*
|
|
53
|
+
* Must be < `highSampleSize`.
|
|
54
|
+
* @default 5
|
|
55
|
+
*/
|
|
56
|
+
lowSampleSize: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Rejection precedent weights (OQ-12.5).
|
|
60
|
+
*
|
|
61
|
+
* These weights are stored on each `ProposalRejectionRecord` and averaged
|
|
62
|
+
* by `computeRejectionPrecedentFactor()` to suppress future proposal
|
|
63
|
+
* confidence for repeatedly-rejected fields.
|
|
64
|
+
*/
|
|
65
|
+
export interface RejectionPrecedentWeightsConfig {
|
|
66
|
+
/**
|
|
67
|
+
* Weight when the rejected proposal had HIGH confidence.
|
|
68
|
+
* Higher weight = stronger suppression of future proposals.
|
|
69
|
+
* @default 0.8
|
|
70
|
+
*/
|
|
71
|
+
highConfidenceRejection: number;
|
|
72
|
+
/**
|
|
73
|
+
* Weight when the rejected proposal had MEDIUM confidence.
|
|
74
|
+
* @default 0.5
|
|
75
|
+
*/
|
|
76
|
+
mediumConfidenceRejection: number;
|
|
77
|
+
/**
|
|
78
|
+
* Weight when the rejected proposal had LOW confidence.
|
|
79
|
+
* @default 0.2
|
|
80
|
+
*/
|
|
81
|
+
lowConfidenceRejection: number;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Rejection precedent configuration block (OQ-12.5).
|
|
85
|
+
*/
|
|
86
|
+
export interface RejectionPrecedentConfig {
|
|
87
|
+
weights: RejectionPrecedentWeightsConfig;
|
|
88
|
+
/**
|
|
89
|
+
* Minimum value returned by `computeRejectionPrecedentFactor()`.
|
|
90
|
+
* Prevents the precedent factor from suppressing proposals entirely.
|
|
91
|
+
*
|
|
92
|
+
* Formula: `factor = max(confidencePenaltyFloor, 1.0 - avgWeight × 0.5)`
|
|
93
|
+
* @default 0.2
|
|
94
|
+
*/
|
|
95
|
+
confidencePenaltyFloor: number;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Raw (partial) calibration config shape as it appears in `calibration.yaml`.
|
|
99
|
+
* All fields are optional; missing values fall back to defaults.
|
|
100
|
+
*/
|
|
101
|
+
export interface RevisionProposalCalibrationConfig {
|
|
102
|
+
/** Fields that should never receive auto-proposals (OQ-12.3 — existing). */
|
|
103
|
+
lockNoProposal?: string[];
|
|
104
|
+
/** Override confidence thresholds (OQ-12.1). */
|
|
105
|
+
confidenceThresholds?: Partial<ConfidenceThresholdsConfig>;
|
|
106
|
+
/** Override rejection precedent weights + floor (OQ-12.5). */
|
|
107
|
+
rejectionPrecedent?: {
|
|
108
|
+
weights?: Partial<RejectionPrecedentWeightsConfig>;
|
|
109
|
+
confidencePenaltyFloor?: number;
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
/**
|
|
113
|
+
* Fully-resolved calibration config — all optional fields replaced with
|
|
114
|
+
* defaults. This is the shape passed to the revision-proposal functions.
|
|
115
|
+
*/
|
|
116
|
+
export interface ResolvedRevisionProposalCalibrationConfig {
|
|
117
|
+
lockNoProposal: string[];
|
|
118
|
+
confidenceThresholds: ConfidenceThresholdsConfig;
|
|
119
|
+
rejectionPrecedent: RejectionPrecedentConfig;
|
|
120
|
+
}
|
|
121
|
+
/** The compile-time default resolved config (shipped AISDLC-271 values). */
|
|
122
|
+
export declare const DEFAULT_RESOLVED_CALIBRATION_CONFIG: ResolvedRevisionProposalCalibrationConfig;
|
|
123
|
+
export interface ConfigValidationError {
|
|
124
|
+
field: string;
|
|
125
|
+
message: string;
|
|
126
|
+
}
|
|
127
|
+
export type ConfigValidationResult = {
|
|
128
|
+
valid: true;
|
|
129
|
+
} | {
|
|
130
|
+
valid: false;
|
|
131
|
+
errors: ConfigValidationError[];
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* Validate a partial calibration config against the RFC-0031 §12.6 rules.
|
|
135
|
+
*
|
|
136
|
+
* Rules:
|
|
137
|
+
* - `highSampleSize > lowSampleSize > 0`
|
|
138
|
+
* - all weights in `[0, 1]`
|
|
139
|
+
* - `confidencePenaltyFloor` in `[0, 1]`
|
|
140
|
+
*
|
|
141
|
+
* Missing fields default to the shipped values and are not validated
|
|
142
|
+
* (a partial config that omits a field is always valid for that field).
|
|
143
|
+
*/
|
|
144
|
+
export declare function validateRevisionProposalCalibrationConfig(config: RevisionProposalCalibrationConfig): ConfigValidationResult;
|
|
145
|
+
/**
|
|
146
|
+
* Merge a partial `RevisionProposalCalibrationConfig` with defaults to
|
|
147
|
+
* produce a fully-resolved config. Does NOT validate — call
|
|
148
|
+
* `validateRevisionProposalCalibrationConfig()` first if you need to
|
|
149
|
+
* surface errors to the operator.
|
|
150
|
+
*/
|
|
151
|
+
export declare function resolveRevisionProposalCalibrationConfig(config?: RevisionProposalCalibrationConfig): ResolvedRevisionProposalCalibrationConfig;
|
|
152
|
+
/**
|
|
153
|
+
* Parse and validate a `.ai-sdlc/calibration.yaml` file's content.
|
|
154
|
+
*
|
|
155
|
+
* Expected top-level shape:
|
|
156
|
+
* ```yaml
|
|
157
|
+
* calibration:
|
|
158
|
+
* lockNoProposal: [...]
|
|
159
|
+
* confidenceThresholds:
|
|
160
|
+
* highSampleSize: 20
|
|
161
|
+
* lowSampleSize: 5
|
|
162
|
+
* rejectionPrecedent:
|
|
163
|
+
* weights:
|
|
164
|
+
* highConfidenceRejection: 0.8
|
|
165
|
+
* mediumConfidenceRejection: 0.5
|
|
166
|
+
* lowConfidenceRejection: 0.2
|
|
167
|
+
* confidencePenaltyFloor: 0.2
|
|
168
|
+
* ```
|
|
169
|
+
*
|
|
170
|
+
* Missing fields are filled with defaults. Validation failures throw with
|
|
171
|
+
* a descriptive message listing all constraint violations.
|
|
172
|
+
*
|
|
173
|
+
* @param yamlContent Raw UTF-8 content of `calibration.yaml`.
|
|
174
|
+
* @returns Fully-resolved config ready to pass to revision-proposal functions.
|
|
175
|
+
* @throws {Error} When the YAML fails RFC-0031 §12.6 validation rules.
|
|
176
|
+
*/
|
|
177
|
+
export declare function parseRevisionProposalCalibrationYaml(yamlContent: string): ResolvedRevisionProposalCalibrationConfig;
|
|
178
|
+
//# sourceMappingURL=revision-proposal-config.d.ts.map
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Per-org calibration.yaml configuration for RFC-0031 DIDRevisionProposal
|
|
3
|
+
* mechanism (Refit AISDLC-310).
|
|
4
|
+
*
|
|
5
|
+
* Exposes OQ-12.1 (confidence thresholds) and OQ-12.5 (rejection weights +
|
|
6
|
+
* penalty floor) as per-org configurable values. Defaults match the values
|
|
7
|
+
* shipped by AISDLC-271 / PR #476 and operator-affirmed during the 2026-05-16
|
|
8
|
+
* audit (RFC-0031 §12.1 + §12.5 resolutions).
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* 1. Load the `.ai-sdlc/calibration.yaml` file.
|
|
12
|
+
* 2. Call `parseRevisionProposalCalibrationYaml(content)` — validates +
|
|
13
|
+
* returns a fully-resolved config with all defaults filled in.
|
|
14
|
+
* 3. Pass the resolved config to `computeConfidence()`,
|
|
15
|
+
* `recordRejection()`, and `computeRejectionPrecedentFactor()`.
|
|
16
|
+
*
|
|
17
|
+
* Validation rules (enforced at load time):
|
|
18
|
+
* - `highSampleSize > lowSampleSize > 0`
|
|
19
|
+
* - All weights in `[0, 1]`
|
|
20
|
+
* - `confidencePenaltyFloor` in `[0, 1]`
|
|
21
|
+
*/
|
|
22
|
+
import { parse as parseYaml } from 'yaml';
|
|
23
|
+
// ── Default constants ─────────────────────────────────────────────────
|
|
24
|
+
/** Minimum total signals (dismiss + escalate + drift) for HIGH confidence. */
|
|
25
|
+
export const DEFAULT_CONFIDENCE_HIGH_SAMPLE_SIZE = 20;
|
|
26
|
+
/** Below this total signal count the proposal is LOW confidence. */
|
|
27
|
+
export const DEFAULT_CONFIDENCE_LOW_SAMPLE_SIZE = 5;
|
|
28
|
+
/** Rejection precedent weight applied when the rejected proposal had HIGH confidence. */
|
|
29
|
+
export const DEFAULT_REJECTION_WEIGHT_HIGH = 0.8;
|
|
30
|
+
/** Rejection precedent weight applied when the rejected proposal had MEDIUM confidence. */
|
|
31
|
+
export const DEFAULT_REJECTION_WEIGHT_MEDIUM = 0.5;
|
|
32
|
+
/** Rejection precedent weight applied when the rejected proposal had LOW confidence. */
|
|
33
|
+
export const DEFAULT_REJECTION_WEIGHT_LOW = 0.2;
|
|
34
|
+
/**
|
|
35
|
+
* Minimum value for the rejection precedent factor.
|
|
36
|
+
* 0.2 = at most 80% suppression of future proposal confidence.
|
|
37
|
+
*/
|
|
38
|
+
export const DEFAULT_CONFIDENCE_PENALTY_FLOOR = 0.2;
|
|
39
|
+
/** The compile-time default resolved config (shipped AISDLC-271 values). */
|
|
40
|
+
export const DEFAULT_RESOLVED_CALIBRATION_CONFIG = {
|
|
41
|
+
lockNoProposal: [],
|
|
42
|
+
confidenceThresholds: {
|
|
43
|
+
highSampleSize: DEFAULT_CONFIDENCE_HIGH_SAMPLE_SIZE,
|
|
44
|
+
lowSampleSize: DEFAULT_CONFIDENCE_LOW_SAMPLE_SIZE,
|
|
45
|
+
},
|
|
46
|
+
rejectionPrecedent: {
|
|
47
|
+
weights: {
|
|
48
|
+
highConfidenceRejection: DEFAULT_REJECTION_WEIGHT_HIGH,
|
|
49
|
+
mediumConfidenceRejection: DEFAULT_REJECTION_WEIGHT_MEDIUM,
|
|
50
|
+
lowConfidenceRejection: DEFAULT_REJECTION_WEIGHT_LOW,
|
|
51
|
+
},
|
|
52
|
+
confidencePenaltyFloor: DEFAULT_CONFIDENCE_PENALTY_FLOOR,
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* Validate a partial calibration config against the RFC-0031 §12.6 rules.
|
|
57
|
+
*
|
|
58
|
+
* Rules:
|
|
59
|
+
* - `highSampleSize > lowSampleSize > 0`
|
|
60
|
+
* - all weights in `[0, 1]`
|
|
61
|
+
* - `confidencePenaltyFloor` in `[0, 1]`
|
|
62
|
+
*
|
|
63
|
+
* Missing fields default to the shipped values and are not validated
|
|
64
|
+
* (a partial config that omits a field is always valid for that field).
|
|
65
|
+
*/
|
|
66
|
+
export function validateRevisionProposalCalibrationConfig(config) {
|
|
67
|
+
const errors = [];
|
|
68
|
+
// ── Confidence thresholds ────────────────────────────────────────
|
|
69
|
+
const thresholds = config.confidenceThresholds;
|
|
70
|
+
if (thresholds !== undefined) {
|
|
71
|
+
const high = thresholds.highSampleSize ?? DEFAULT_CONFIDENCE_HIGH_SAMPLE_SIZE;
|
|
72
|
+
const low = thresholds.lowSampleSize ?? DEFAULT_CONFIDENCE_LOW_SAMPLE_SIZE;
|
|
73
|
+
if (thresholds.lowSampleSize !== undefined && thresholds.lowSampleSize <= 0) {
|
|
74
|
+
errors.push({
|
|
75
|
+
field: 'confidenceThresholds.lowSampleSize',
|
|
76
|
+
message: `must be > 0 (got ${thresholds.lowSampleSize})`,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
if (thresholds.highSampleSize !== undefined && thresholds.highSampleSize <= 0) {
|
|
80
|
+
errors.push({
|
|
81
|
+
field: 'confidenceThresholds.highSampleSize',
|
|
82
|
+
message: `must be > 0 (got ${thresholds.highSampleSize})`,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// highSampleSize must be strictly greater than lowSampleSize
|
|
86
|
+
if (high <= low) {
|
|
87
|
+
errors.push({
|
|
88
|
+
field: 'confidenceThresholds',
|
|
89
|
+
message: `highSampleSize (${high}) must be > lowSampleSize (${low})`,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// ── Rejection precedent ──────────────────────────────────────────
|
|
94
|
+
const rp = config.rejectionPrecedent;
|
|
95
|
+
if (rp !== undefined) {
|
|
96
|
+
const weights = rp.weights;
|
|
97
|
+
if (weights !== undefined) {
|
|
98
|
+
const weightFields = [
|
|
99
|
+
['highConfidenceRejection', weights.highConfidenceRejection],
|
|
100
|
+
['mediumConfidenceRejection', weights.mediumConfidenceRejection],
|
|
101
|
+
['lowConfidenceRejection', weights.lowConfidenceRejection],
|
|
102
|
+
];
|
|
103
|
+
for (const [key, value] of weightFields) {
|
|
104
|
+
if (value !== undefined && (value < 0 || value > 1)) {
|
|
105
|
+
errors.push({
|
|
106
|
+
field: `rejectionPrecedent.weights.${key}`,
|
|
107
|
+
message: `must be in [0, 1] (got ${value})`,
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if (rp.confidencePenaltyFloor !== undefined &&
|
|
113
|
+
(rp.confidencePenaltyFloor < 0 || rp.confidencePenaltyFloor > 1)) {
|
|
114
|
+
errors.push({
|
|
115
|
+
field: 'rejectionPrecedent.confidencePenaltyFloor',
|
|
116
|
+
message: `must be in [0, 1] (got ${rp.confidencePenaltyFloor})`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
if (errors.length > 0)
|
|
121
|
+
return { valid: false, errors };
|
|
122
|
+
return { valid: true };
|
|
123
|
+
}
|
|
124
|
+
// ── Resolution (merge partial config with defaults) ───────────────────
|
|
125
|
+
/**
|
|
126
|
+
* Merge a partial `RevisionProposalCalibrationConfig` with defaults to
|
|
127
|
+
* produce a fully-resolved config. Does NOT validate — call
|
|
128
|
+
* `validateRevisionProposalCalibrationConfig()` first if you need to
|
|
129
|
+
* surface errors to the operator.
|
|
130
|
+
*/
|
|
131
|
+
export function resolveRevisionProposalCalibrationConfig(config = {}) {
|
|
132
|
+
const d = DEFAULT_RESOLVED_CALIBRATION_CONFIG;
|
|
133
|
+
return {
|
|
134
|
+
lockNoProposal: config.lockNoProposal ?? d.lockNoProposal,
|
|
135
|
+
confidenceThresholds: {
|
|
136
|
+
highSampleSize: config.confidenceThresholds?.highSampleSize ?? d.confidenceThresholds.highSampleSize,
|
|
137
|
+
lowSampleSize: config.confidenceThresholds?.lowSampleSize ?? d.confidenceThresholds.lowSampleSize,
|
|
138
|
+
},
|
|
139
|
+
rejectionPrecedent: {
|
|
140
|
+
weights: {
|
|
141
|
+
highConfidenceRejection: config.rejectionPrecedent?.weights?.highConfidenceRejection ??
|
|
142
|
+
d.rejectionPrecedent.weights.highConfidenceRejection,
|
|
143
|
+
mediumConfidenceRejection: config.rejectionPrecedent?.weights?.mediumConfidenceRejection ??
|
|
144
|
+
d.rejectionPrecedent.weights.mediumConfidenceRejection,
|
|
145
|
+
lowConfidenceRejection: config.rejectionPrecedent?.weights?.lowConfidenceRejection ??
|
|
146
|
+
d.rejectionPrecedent.weights.lowConfidenceRejection,
|
|
147
|
+
},
|
|
148
|
+
confidencePenaltyFloor: config.rejectionPrecedent?.confidencePenaltyFloor ??
|
|
149
|
+
d.rejectionPrecedent.confidencePenaltyFloor,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
// ── YAML loading ──────────────────────────────────────────────────────
|
|
154
|
+
/**
|
|
155
|
+
* Parse and validate a `.ai-sdlc/calibration.yaml` file's content.
|
|
156
|
+
*
|
|
157
|
+
* Expected top-level shape:
|
|
158
|
+
* ```yaml
|
|
159
|
+
* calibration:
|
|
160
|
+
* lockNoProposal: [...]
|
|
161
|
+
* confidenceThresholds:
|
|
162
|
+
* highSampleSize: 20
|
|
163
|
+
* lowSampleSize: 5
|
|
164
|
+
* rejectionPrecedent:
|
|
165
|
+
* weights:
|
|
166
|
+
* highConfidenceRejection: 0.8
|
|
167
|
+
* mediumConfidenceRejection: 0.5
|
|
168
|
+
* lowConfidenceRejection: 0.2
|
|
169
|
+
* confidencePenaltyFloor: 0.2
|
|
170
|
+
* ```
|
|
171
|
+
*
|
|
172
|
+
* Missing fields are filled with defaults. Validation failures throw with
|
|
173
|
+
* a descriptive message listing all constraint violations.
|
|
174
|
+
*
|
|
175
|
+
* @param yamlContent Raw UTF-8 content of `calibration.yaml`.
|
|
176
|
+
* @returns Fully-resolved config ready to pass to revision-proposal functions.
|
|
177
|
+
* @throws {Error} When the YAML fails RFC-0031 §12.6 validation rules.
|
|
178
|
+
*/
|
|
179
|
+
export function parseRevisionProposalCalibrationYaml(yamlContent) {
|
|
180
|
+
const doc = parseYaml(yamlContent);
|
|
181
|
+
const raw = (doc?.calibration ?? {});
|
|
182
|
+
const config = {
|
|
183
|
+
lockNoProposal: Array.isArray(raw.lockNoProposal) ? raw.lockNoProposal : undefined,
|
|
184
|
+
confidenceThresholds: raw.confidenceThresholds !== null && typeof raw.confidenceThresholds === 'object'
|
|
185
|
+
? raw.confidenceThresholds
|
|
186
|
+
: undefined,
|
|
187
|
+
rejectionPrecedent: raw.rejectionPrecedent !== null && typeof raw.rejectionPrecedent === 'object'
|
|
188
|
+
? raw.rejectionPrecedent
|
|
189
|
+
: undefined,
|
|
190
|
+
};
|
|
191
|
+
const validation = validateRevisionProposalCalibrationConfig(config);
|
|
192
|
+
if (!validation.valid) {
|
|
193
|
+
const lines = validation.errors.map((e) => ` ${e.field}: ${e.message}`).join('\n');
|
|
194
|
+
throw new Error(`calibration.yaml validation failed (RFC-0031 §12.6):\n${lines}`);
|
|
195
|
+
}
|
|
196
|
+
return resolveRevisionProposalCalibrationConfig(config);
|
|
197
|
+
}
|
|
198
|
+
//# sourceMappingURL=revision-proposal-config.js.map
|