@encore-os/eos-spec 0.3.1 → 0.5.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/commands/audit.js +11 -3
- package/dist/commands/audit.js.map +1 -1
- package/dist/commands/complete.js +41 -14
- package/dist/commands/complete.js.map +1 -1
- package/dist/commands/conformance.js +27 -0
- package/dist/commands/conformance.js.map +1 -1
- package/dist/commands/gen-tests.js +5 -2
- package/dist/commands/gen-tests.js.map +1 -1
- package/dist/commands/init.js +96 -22
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/next.d.ts +20 -4
- package/dist/commands/next.js +53 -15
- package/dist/commands/next.js.map +1 -1
- package/dist/commands/precedent.d.ts +2 -0
- package/dist/commands/precedent.js +12 -3
- package/dist/commands/precedent.js.map +1 -1
- package/dist/commands/reconcile.d.ts +3 -10
- package/dist/commands/reconcile.js +6 -37
- package/dist/commands/reconcile.js.map +1 -1
- package/dist/commands/signoff.js +33 -5
- package/dist/commands/signoff.js.map +1 -1
- package/dist/commands/verify-acs.js +7 -4
- package/dist/commands/verify-acs.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +15 -3
- package/dist/index.js.map +1 -1
- package/dist/lib/code-evidence.js +2 -1
- package/dist/lib/code-evidence.js.map +1 -1
- package/dist/lib/coherence.d.ts +2 -2
- package/dist/lib/coherence.js +7 -6
- package/dist/lib/coherence.js.map +1 -1
- package/dist/lib/config.d.ts +34 -2
- package/dist/lib/config.js +45 -3
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/discovery-defaults.d.ts +20 -0
- package/dist/lib/discovery-defaults.js +21 -0
- package/dist/lib/discovery-defaults.js.map +1 -0
- package/dist/lib/embedding-store.d.ts +0 -2
- package/dist/lib/embedding-store.js +1 -1
- package/dist/lib/embedding-store.js.map +1 -1
- package/dist/lib/exec.d.ts +0 -2
- package/dist/lib/exec.js +1 -12
- package/dist/lib/exec.js.map +1 -1
- package/dist/lib/frontmatter.d.ts +5 -1
- package/dist/lib/frontmatter.js.map +1 -1
- package/dist/lib/migration-collision.d.ts +5 -4
- package/dist/lib/migration-collision.js +8 -6
- package/dist/lib/migration-collision.js.map +1 -1
- package/dist/lib/next-action.d.ts +19 -2
- package/dist/lib/next-action.js +28 -6
- package/dist/lib/next-action.js.map +1 -1
- package/dist/lib/ollama-embed.d.ts +0 -9
- package/dist/lib/ollama-embed.js +0 -35
- package/dist/lib/ollama-embed.js.map +1 -1
- package/dist/lib/pipeline-config.js +40 -2
- package/dist/lib/pipeline-config.js.map +1 -1
- package/dist/lib/pipeline-map.d.ts +30 -0
- package/dist/lib/pipeline-map.js +86 -5
- package/dist/lib/pipeline-map.js.map +1 -1
- package/dist/lib/pipeline-schema.d.ts +25 -1
- package/dist/lib/pipeline-schema.js +3 -0
- package/dist/lib/pipeline-schema.js.map +1 -1
- package/dist/lib/predicate-registry.js +28 -1
- package/dist/lib/predicate-registry.js.map +1 -1
- package/dist/lib/reconcile-core.d.ts +26 -0
- package/dist/lib/reconcile-core.js +43 -0
- package/dist/lib/reconcile-core.js.map +1 -0
- package/dist/lib/scaffold-templates.d.ts +30 -0
- package/dist/lib/scaffold-templates.js +203 -0
- package/dist/lib/scaffold-templates.js.map +1 -0
- package/dist/lib/spec-pure.js +44 -1
- package/dist/lib/spec-pure.js.map +1 -1
- package/dist/lib/specs.d.ts +17 -0
- package/dist/lib/specs.js.map +1 -1
- package/dist/lib/test-generator.d.ts +1 -1
- package/dist/lib/test-generator.js +3 -2
- package/dist/lib/test-generator.js.map +1 -1
- package/dist/lib/verifies-scan.d.ts +5 -1
- package/dist/lib/verifies-scan.js +9 -3
- package/dist/lib/verifies-scan.js.map +1 -1
- package/package.json +4 -4
|
@@ -19,10 +19,24 @@ export type StageDef = {
|
|
|
19
19
|
invocation: string;
|
|
20
20
|
/** Human-readable reason shown when this is the next step. */
|
|
21
21
|
reason: string;
|
|
22
|
-
/** Only applies to regulated cores (cl/pm/hr/rh/gr).
|
|
22
|
+
/** Only applies to regulated cores (cl/pm/hr/rh/gr). Shorthand for an
|
|
23
|
+
* applicability predicate keyed on `isRegulated`. */
|
|
23
24
|
regulatedOnly?: boolean;
|
|
25
|
+
/** Name of a registry predicate that decides whether this stage applies to a
|
|
26
|
+
* given spec — the general form of `regulatedOnly`. When set, the stage is
|
|
27
|
+
* walked (and contributes to `computeStage`) ONLY for specs the predicate
|
|
28
|
+
* accepts, regardless of core. Used to widen the compliance gate beyond the
|
|
29
|
+
* regulated cores to PHI/PII-bearing specs (encore1 `complianceGating`, #1372)
|
|
30
|
+
* without hardcoding that logic into the engine — the builder layout, which has
|
|
31
|
+
* no compliance stage, never references it. Takes precedence over `regulatedOnly`. */
|
|
32
|
+
appliesWhen?: string;
|
|
24
33
|
/** Advisory — surfaced as a hint but never blocks progression. */
|
|
25
34
|
optional?: boolean;
|
|
35
|
+
/** Phase 1 parity gate: this stage participates in the navigator walk ONLY under
|
|
36
|
+
* `next --strict`. It carries no `completesStatus` (never moves computeStage), so
|
|
37
|
+
* default `next`/`computeStage`/`reconcile` are unaffected; under `--strict` it
|
|
38
|
+
* surfaces as a BLOCKING action when its gate is unmet. */
|
|
39
|
+
strictOnly?: boolean;
|
|
26
40
|
/** The pipeline_status enum value this transition completes (for schema-coverage + reconciliation). */
|
|
27
41
|
completesStatus?: string;
|
|
28
42
|
};
|
|
@@ -41,6 +55,16 @@ export type PipelineSchema = {
|
|
|
41
55
|
statusOrder: string[];
|
|
42
56
|
stages: StageDef[];
|
|
43
57
|
caps: CapDef[];
|
|
58
|
+
/** When true, the NAVIGATOR treats a not-done stage as satisfied if its
|
|
59
|
+
* `completesStatus` ranks strictly BELOW the spec's computed stage — i.e. a
|
|
60
|
+
* later stage's artifact already exists, so a missing earlier (soft) marker is
|
|
61
|
+
* superseded rather than re-surfaced. Models encoreos's #1593 behavior: a spec
|
|
62
|
+
* reviewed + compliance-signed + planned + tasked but missing the early
|
|
63
|
+
* `<!-- validated: -->` marker routes to the implement/complete tail, not back
|
|
64
|
+
* to validate-spec. `computeStage` is unaffected (it already reports the
|
|
65
|
+
* furthest-reached stage); only `recommendAction`'s walk honors this. Opt-in
|
|
66
|
+
* per layout — the builder layout omits it (default false) and is unchanged. */
|
|
67
|
+
supersedeSoftGates?: boolean;
|
|
44
68
|
};
|
|
45
69
|
/** Validate a {@link PipelineSchema} against its {@link PredicateRegistry}: every
|
|
46
70
|
* stage gate and cap predicate must be registered, and every `completesStatus`/
|
|
@@ -6,6 +6,9 @@ export function validateSchema(schema, registry) {
|
|
|
6
6
|
if (!registry[st.gate]) {
|
|
7
7
|
throw new Error(`pipeline schema: unknown gate predicate '${st.gate}' for stage '${st.id}'`);
|
|
8
8
|
}
|
|
9
|
+
if (st.appliesWhen && !registry[st.appliesWhen]) {
|
|
10
|
+
throw new Error(`pipeline schema: unknown appliesWhen predicate '${st.appliesWhen}' for stage '${st.id}'`);
|
|
11
|
+
}
|
|
9
12
|
if (st.completesStatus && !schema.statusOrder.includes(st.completesStatus)) {
|
|
10
13
|
throw new Error(`pipeline schema: stage '${st.id}' completesStatus '${st.completesStatus}' not in statusOrder`);
|
|
11
14
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pipeline-schema.js","sourceRoot":"","sources":["../../src/lib/pipeline-schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pipeline-schema.js","sourceRoot":"","sources":["../../src/lib/pipeline-schema.ts"],"names":[],"mappings":"AA2EA;;wEAEwE;AACxE,MAAM,UAAU,cAAc,CAAC,MAAsB,EAAE,QAA2B;IAChF,KAAK,MAAM,EAAE,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;QAC/B,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;YACvB,MAAM,IAAI,KAAK,CAAC,4CAA4C,EAAE,CAAC,IAAI,gBAAgB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/F,CAAC;QACD,IAAI,EAAE,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,WAAW,CAAC,EAAE,CAAC;YAChD,MAAM,IAAI,KAAK,CAAC,mDAAmD,EAAE,CAAC,WAAW,gBAAgB,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;QAC7G,CAAC;QACD,IAAI,EAAE,CAAC,eAAe,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,eAAe,CAAC,EAAE,CAAC;YAC3E,MAAM,IAAI,KAAK,CAAC,2BAA2B,EAAE,CAAC,EAAE,sBAAsB,EAAE,CAAC,eAAe,sBAAsB,CAAC,CAAC;QAClH,CAAC;IACH,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,2CAA2C,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QAC5E,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,kCAAkC,GAAG,CAAC,QAAQ,sBAAsB,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -11,8 +11,16 @@ export const DEFAULT_PREDICATES = {
|
|
|
11
11
|
hasResearch: (s) => s.signals.hasResearch,
|
|
12
12
|
// spec-review.
|
|
13
13
|
hasSpecReview: (s) => s.signals.hasSpecReview,
|
|
14
|
-
// compliance-review (
|
|
14
|
+
// compliance-review (gate predicate).
|
|
15
15
|
hasComplianceSignoff: (s) => s.signals.hasComplianceSignoff,
|
|
16
|
+
// compliance-review APPLICABILITY (encore1 `appliesWhen`, #1372 PHI-widening):
|
|
17
|
+
// the compliance gate applies to regulated cores AND to PHI/PII/billing/
|
|
18
|
+
// credentialing-bearing specs in ANY core. Reuses the existing `isSensitive`
|
|
19
|
+
// signal (the engine's PHI-bearing detector) rather than a parallel
|
|
20
|
+
// `isPhiBearing`, so there is a single source of the compliance-gating
|
|
21
|
+
// condition. The builder layout has no compliance stage and never references
|
|
22
|
+
// this, so widening it here cannot affect builder.
|
|
23
|
+
complianceGating: (s) => s.signals.isRegulated || Boolean(s.signals.isSensitive),
|
|
16
24
|
// draft-acs: done when there are no user stories, or ACs are drafted.
|
|
17
25
|
acsDraftedOrNoStories: (s) => !s.signals.hasUserStories || s.signals.hasAcceptanceCriteria,
|
|
18
26
|
// generate-tests: ACs absent, OR an active generated suite / verified ACs / linked local test exists (B5 + C1).
|
|
@@ -36,5 +44,24 @@ export const DEFAULT_PREDICATES = {
|
|
|
36
44
|
hasTasks: (s) => s.hasTasks,
|
|
37
45
|
// AC cap predicate (computeStage): caps below tasks_generated when ACs are absent.
|
|
38
46
|
hasAcceptanceCriteria: (s) => s.signals.hasAcceptanceCriteria,
|
|
47
|
+
// ── Phase 1 parity gates (Finding A) — wired as strictOnly schema stages with NO
|
|
48
|
+
// completesStatus, so they NEVER move computeStage (the parity gate is over a
|
|
49
|
+
// fixture corpus that predates these signals). Each is SATISFIED-by-default and
|
|
50
|
+
// only fails once the genuinely-missing condition is present, so the bare CLI's
|
|
51
|
+
// default `next` is unchanged and only `next --strict` surfaces them as BLOCKING.
|
|
52
|
+
// research-before-review: research grounding must precede spec-review on the
|
|
53
|
+
// non-regulated path. Nothing to order until the spec is reviewed; once reviewed,
|
|
54
|
+
// a research appendix must exist. (Regulated cores already hard-order research via
|
|
55
|
+
// the regulatedOnly `ground-research` stage + the research honest-cap.)
|
|
56
|
+
hasResearchBeforeReview: (s) => !s.signals.hasSpecReview || s.signals.hasResearch,
|
|
57
|
+
// revalidate-after-review: spec-review auto-applies edits; the pipeline re-runs
|
|
58
|
+
// validate-spec to catch what they broke. Satisfied until the spec is reviewed;
|
|
59
|
+
// once reviewed, a `<!-- revalidated-after-review: -->` marker must be present.
|
|
60
|
+
hasReValidationAfterReview: (s) => !s.signals.hasSpecReview || Boolean(s.signals.hasReValidationAfterReview),
|
|
61
|
+
// compliance-for-sensitive: a spec carrying a PHI/PII/billing/credentialing signal
|
|
62
|
+
// (ANY core, not just regulated) needs a compliance sign-off. Non-sensitive specs
|
|
63
|
+
// pass. This ADDS the sensitive-non-regulated path; it does NOT replace the
|
|
64
|
+
// regulated-core `compliance-review` stage (which still gates on `hasComplianceSignoff`).
|
|
65
|
+
hasComplianceForSensitive: (s) => !s.signals.isSensitive || s.signals.hasComplianceSignoff,
|
|
39
66
|
};
|
|
40
67
|
//# sourceMappingURL=predicate-registry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"predicate-registry.js","sourceRoot":"","sources":["../../src/lib/predicate-registry.ts"],"names":[],"mappings":"AAEA;;;sFAGsF;AACtF,MAAM,CAAC,MAAM,kBAAkB,GAAsB;IACnD,kFAAkF;IAClF,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU;IAC/B,6CAA6C;IAC7C,oBAAoB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,oBAAoB;IAC3D,+EAA+E;IAC/E,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW;IACzC,eAAe;IACf,aAAa,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,aAAa;IAC7C,
|
|
1
|
+
{"version":3,"file":"predicate-registry.js","sourceRoot":"","sources":["../../src/lib/predicate-registry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { SpecFile } from './specs.js';
|
|
2
|
+
/**
|
|
3
|
+
* The per-spec reconcile core, extracted so the `reconcile` command AND the
|
|
4
|
+
* `signoff --reconcile` post-step share ONE implementation and cannot drift
|
|
5
|
+
* (Finding A item 4: `reconcile` was never auto-invoked, so `pipeline_status`
|
|
6
|
+
* silently lagged the artifacts a sign-off had just produced). fs-bound (reads +
|
|
7
|
+
* writes the spec markdown) — stays behind the package main entry, never `/pure`.
|
|
8
|
+
*/
|
|
9
|
+
export type ReconcileDirection = 'ok' | 'lagging' | 'overstated';
|
|
10
|
+
/** Classify frontmatter status vs the artifact-derived stage. */
|
|
11
|
+
export declare function classify(written: string | undefined, computed: string | undefined): ReconcileDirection;
|
|
12
|
+
export type ReconcileRow = {
|
|
13
|
+
id: string;
|
|
14
|
+
core: string;
|
|
15
|
+
written?: string;
|
|
16
|
+
computed?: string;
|
|
17
|
+
direction: ReconcileDirection;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Recompute one spec's pipeline_status from its on-disk artifacts and, when
|
|
21
|
+
* `write` is set, surgically materialize the computed status (plus a healed
|
|
22
|
+
* `artifacts.tasks` pointer) into the spec frontmatter. Returns the divergence
|
|
23
|
+
* row regardless of whether anything was written. Mirrors the inner loop body of
|
|
24
|
+
* the `reconcile` command exactly (the command now delegates here).
|
|
25
|
+
*/
|
|
26
|
+
export declare function reconcileSpec(repoRoot: string, spec: SpecFile, write: boolean): ReconcileRow;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { isAbsolute, join } from 'node:path';
|
|
3
|
+
import { resolveTasksArtifact, setPipelineStatus, setTasksArtifact } from './frontmatter.js';
|
|
4
|
+
import { computeStage, rank } from './pipeline-map.js';
|
|
5
|
+
/** Classify frontmatter status vs the artifact-derived stage. */
|
|
6
|
+
export function classify(written, computed) {
|
|
7
|
+
if (written === computed)
|
|
8
|
+
return 'ok';
|
|
9
|
+
return rank(computed) > rank(written) ? 'lagging' : 'overstated';
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Recompute one spec's pipeline_status from its on-disk artifacts and, when
|
|
13
|
+
* `write` is set, surgically materialize the computed status (plus a healed
|
|
14
|
+
* `artifacts.tasks` pointer) into the spec frontmatter. Returns the divergence
|
|
15
|
+
* row regardless of whether anything was written. Mirrors the inner loop body of
|
|
16
|
+
* the `reconcile` command exactly (the command now delegates here).
|
|
17
|
+
*/
|
|
18
|
+
export function reconcileSpec(repoRoot, spec, write) {
|
|
19
|
+
const computed = computeStage(spec);
|
|
20
|
+
const written = spec.signals.pipelineStatus;
|
|
21
|
+
const direction = classify(written, computed);
|
|
22
|
+
if (write && computed) {
|
|
23
|
+
const original = readFileSync(spec.path, 'utf8');
|
|
24
|
+
let text = original;
|
|
25
|
+
if (direction !== 'ok')
|
|
26
|
+
text = setPipelineStatus(text, computed);
|
|
27
|
+
// Materialize artifacts.tasks alongside pipeline_status so a spec that reaches
|
|
28
|
+
// tasks_generated satisfies the pipeline-status validator (pipeline/missing-
|
|
29
|
+
// tasks-artifact) without hand-editing (#997 Bug 2). Non-destructive: a VALID
|
|
30
|
+
// existing pointer is preserved; only an absent or stale pointer is set to the
|
|
31
|
+
// canonical path, and only when that canonical file actually exists (#16).
|
|
32
|
+
if (spec.hasTasks) {
|
|
33
|
+
const fileExists = (rel) => existsSync(isAbsolute(rel) ? rel : join(repoRoot, rel));
|
|
34
|
+
const next = resolveTasksArtifact(text, `specs/${spec.core}/tasks/${spec.id}-TASKS.md`, fileExists);
|
|
35
|
+
if (next)
|
|
36
|
+
text = setTasksArtifact(text, next);
|
|
37
|
+
}
|
|
38
|
+
if (text !== original)
|
|
39
|
+
writeFileSync(spec.path, text, 'utf8');
|
|
40
|
+
}
|
|
41
|
+
return { id: spec.id, core: spec.core, written, computed, direction };
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=reconcile-core.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reconcile-core.js","sourceRoot":"","sources":["../../src/lib/reconcile-core.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,oBAAoB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAC7F,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,mBAAmB,CAAC;AAavD,iEAAiE;AACjE,MAAM,UAAU,QAAQ,CAAC,OAA2B,EAAE,QAA4B;IAChF,IAAI,OAAO,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACtC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,CAAC;AACnE,CAAC;AAUD;;;;;;GAMG;AACH,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,IAAc,EAAE,KAAc;IAC5E,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC;IAC5C,MAAM,SAAS,GAAG,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC9C,IAAI,KAAK,IAAI,QAAQ,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACjD,IAAI,IAAI,GAAG,QAAQ,CAAC;QACpB,IAAI,SAAS,KAAK,IAAI;YAAE,IAAI,GAAG,iBAAiB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QACjE,+EAA+E;QAC/E,6EAA6E;QAC7E,8EAA8E;QAC9E,+EAA+E;QAC/E,2EAA2E;QAC3E,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClB,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC;YAC5F,MAAM,IAAI,GAAG,oBAAoB,CAAC,IAAI,EAAE,SAAS,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;YACpG,IAAI,IAAI;gBAAE,IAAI,GAAG,gBAAgB,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;QAChD,CAAC;QACD,IAAI,IAAI,KAAK,QAAQ;YAAE,aAAa,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inlined scaffold content for `eos-spec init --scaffold` (TOOL-03 AC-5). The npm
|
|
3
|
+
* tarball ships only `dist/` + `bin/` (package.json `files`), so a bootstrap must
|
|
4
|
+
* carry its config + template bodies as compiled string constants — there is no
|
|
5
|
+
* `templates/` data dir in the published package. This module is fs-free: it holds
|
|
6
|
+
* only strings, so `init.ts` writes them with its own never-clobber primitive.
|
|
7
|
+
*
|
|
8
|
+
* The templates are intentionally minimal, valid stubs (mirroring the engine's own
|
|
9
|
+
* test corpus). `create` fills the `{{ID}}/{{CORE}}/{{TITLE}}/{{DATE}}` placeholders
|
|
10
|
+
* via `applyHeader`; `init --scaffold` writes the template files verbatim (the
|
|
11
|
+
* placeholders are for `create`, not for scaffolding) and only interpolates the
|
|
12
|
+
* config's `last_updated`.
|
|
13
|
+
*/
|
|
14
|
+
/** Relative path (from repo root) of the scaffolded config. */
|
|
15
|
+
export declare const SCAFFOLD_CONFIG_PATH = "specs/config.yaml";
|
|
16
|
+
/**
|
|
17
|
+
* A portable default `specs/config.yaml`. One example core (`app`); a consumer edits
|
|
18
|
+
* `cores:` to match their domain. Carries the optional TOOL-03 discovery-path keys
|
|
19
|
+
* with their fork-layout defaults made explicit, so a new repo sees how to retarget
|
|
20
|
+
* `paths.migrations` / `generated_tests` / `verifies_*` for its own layout.
|
|
21
|
+
*/
|
|
22
|
+
export declare function defaultConfigYaml(lastUpdated: string): string;
|
|
23
|
+
/**
|
|
24
|
+
* Template files written under \`specs/_templates/\` by \`init --scaffold\`, verbatim
|
|
25
|
+
* (placeholders intact). \`rel\` is relative to repo root.
|
|
26
|
+
*/
|
|
27
|
+
export declare const SCAFFOLD_TEMPLATE_FILES: ReadonlyArray<{
|
|
28
|
+
rel: string;
|
|
29
|
+
content: string;
|
|
30
|
+
}>;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Inlined scaffold content for `eos-spec init --scaffold` (TOOL-03 AC-5). The npm
|
|
3
|
+
* tarball ships only `dist/` + `bin/` (package.json `files`), so a bootstrap must
|
|
4
|
+
* carry its config + template bodies as compiled string constants — there is no
|
|
5
|
+
* `templates/` data dir in the published package. This module is fs-free: it holds
|
|
6
|
+
* only strings, so `init.ts` writes them with its own never-clobber primitive.
|
|
7
|
+
*
|
|
8
|
+
* The templates are intentionally minimal, valid stubs (mirroring the engine's own
|
|
9
|
+
* test corpus). `create` fills the `{{ID}}/{{CORE}}/{{TITLE}}/{{DATE}}` placeholders
|
|
10
|
+
* via `applyHeader`; `init --scaffold` writes the template files verbatim (the
|
|
11
|
+
* placeholders are for `create`, not for scaffolding) and only interpolates the
|
|
12
|
+
* config's `last_updated`.
|
|
13
|
+
*/
|
|
14
|
+
/** Relative path (from repo root) of the scaffolded config. */
|
|
15
|
+
export const SCAFFOLD_CONFIG_PATH = 'specs/config.yaml';
|
|
16
|
+
/**
|
|
17
|
+
* A portable default `specs/config.yaml`. One example core (`app`); a consumer edits
|
|
18
|
+
* `cores:` to match their domain. Carries the optional TOOL-03 discovery-path keys
|
|
19
|
+
* with their fork-layout defaults made explicit, so a new repo sees how to retarget
|
|
20
|
+
* `paths.migrations` / `generated_tests` / `verifies_*` for its own layout.
|
|
21
|
+
*/
|
|
22
|
+
export function defaultConfigYaml(lastUpdated) {
|
|
23
|
+
return `# Spec workflow configuration — consumed by the @encore-os/eos-spec engine.
|
|
24
|
+
# Scaffolded by \`eos-spec init --scaffold\`. Edit \`cores:\` to match your domain,
|
|
25
|
+
# then \`eos-spec create <CORE>-01 "Title"\` to author your first spec.
|
|
26
|
+
version: 1
|
|
27
|
+
last_updated: ${lastUpdated}
|
|
28
|
+
|
|
29
|
+
# Cores that own specs. Order is presentation order. Add one row per area; the id
|
|
30
|
+
# is the spec-id prefix (e.g. core \`app\` ⇒ \`APP-01\`).
|
|
31
|
+
cores:
|
|
32
|
+
- id: app
|
|
33
|
+
name: Application
|
|
34
|
+
|
|
35
|
+
# Pipeline stages — tracked in spec frontmatter as \`pipeline_status:\`.
|
|
36
|
+
pipeline_stages:
|
|
37
|
+
- id: stub
|
|
38
|
+
description: File created, content placeholder
|
|
39
|
+
- id: clarified
|
|
40
|
+
description: Ambiguities resolved
|
|
41
|
+
- id: validated
|
|
42
|
+
description: Structure verified against the template
|
|
43
|
+
- id: reviewed
|
|
44
|
+
description: Review completed
|
|
45
|
+
- id: planned
|
|
46
|
+
description: Implementation plan written
|
|
47
|
+
- id: tasks_generated
|
|
48
|
+
description: TASKS.md created; ready for implementation
|
|
49
|
+
|
|
50
|
+
# Status enum — displayed in spec frontmatter \`status:\`.
|
|
51
|
+
statuses:
|
|
52
|
+
- id: specification
|
|
53
|
+
label: "📋 Specification"
|
|
54
|
+
description: Drafting; not ready to implement
|
|
55
|
+
- id: in_progress
|
|
56
|
+
label: "🔵 In Progress"
|
|
57
|
+
description: Implementation underway
|
|
58
|
+
- id: complete
|
|
59
|
+
label: "✅ Complete"
|
|
60
|
+
description: All tasks complete and validated
|
|
61
|
+
- id: archived
|
|
62
|
+
label: "🗄️ Archived"
|
|
63
|
+
description: Moved to specs/{core}/archive/
|
|
64
|
+
- id: superseded
|
|
65
|
+
label: "📋 Superseded"
|
|
66
|
+
description: Replaced by another spec; kept for traceability
|
|
67
|
+
|
|
68
|
+
# Directory layout (relative to specs/{core}/).
|
|
69
|
+
paths:
|
|
70
|
+
specs: specs
|
|
71
|
+
plans: plans
|
|
72
|
+
tasks: tasks
|
|
73
|
+
archive: archive
|
|
74
|
+
# Discovery paths (TOOL-03). Optional — these defaults match the fork layout;
|
|
75
|
+
# retarget them if your repo keeps migrations / generated tests / @verifies
|
|
76
|
+
# tests elsewhere.
|
|
77
|
+
migrations: supabase/migrations
|
|
78
|
+
generated_tests: e2e/generated
|
|
79
|
+
verifies_scan_roots: [tests, src]
|
|
80
|
+
verifies_backlink_roots: [e2e, src, runner, scripts]
|
|
81
|
+
|
|
82
|
+
# Templates — by intent. Paths are relative to repo root.
|
|
83
|
+
templates:
|
|
84
|
+
full_spec: specs/_templates/SPEC_TEMPLATE.md
|
|
85
|
+
lite_spec: specs/_templates/SPEC_TEMPLATE_LITE.md
|
|
86
|
+
enhancement_single: specs/_templates/SPEC_TEMPLATE_LITE.md
|
|
87
|
+
plan: specs/_templates/PLAN_TEMPLATE.md
|
|
88
|
+
tasks: specs/_templates/TASKS_TEMPLATE.md
|
|
89
|
+
|
|
90
|
+
# Repo rules that override scoring. Empty by default; add your own.
|
|
91
|
+
hard_gates: []
|
|
92
|
+
|
|
93
|
+
# Unified CLI invocations for automation (run from repo root).
|
|
94
|
+
commands:
|
|
95
|
+
unified:
|
|
96
|
+
whats_next: "eos-spec next"
|
|
97
|
+
list: "eos-spec list"
|
|
98
|
+
create: "eos-spec create"
|
|
99
|
+
legacy: {}
|
|
100
|
+
|
|
101
|
+
# Archive policy — what \`eos-spec archive\` does.
|
|
102
|
+
archive:
|
|
103
|
+
enabled: true
|
|
104
|
+
trigger: status_complete_for_n_days
|
|
105
|
+
threshold_days: 30
|
|
106
|
+
destination: specs/{core}/archive/
|
|
107
|
+
preserves:
|
|
108
|
+
- the spec markdown
|
|
109
|
+
removes_from:
|
|
110
|
+
- any index/registry docs listing the spec as active
|
|
111
|
+
|
|
112
|
+
delta_types:
|
|
113
|
+
- additive
|
|
114
|
+
- modifying
|
|
115
|
+
|
|
116
|
+
# Defaults applied when fields are omitted.
|
|
117
|
+
defaults:
|
|
118
|
+
spec_version: "1.0"
|
|
119
|
+
test_coverage_target: 80
|
|
120
|
+
`;
|
|
121
|
+
}
|
|
122
|
+
const SPEC_TEMPLATE = `---
|
|
123
|
+
# Replace placeholder values when authoring.
|
|
124
|
+
id: {{ID}}
|
|
125
|
+
title: "{{TITLE}}"
|
|
126
|
+
core: {{CORE}}
|
|
127
|
+
status: specification
|
|
128
|
+
version: "1.0"
|
|
129
|
+
created: "{{DATE}}"
|
|
130
|
+
updated: "{{DATE}}"
|
|
131
|
+
pipeline_status: stub
|
|
132
|
+
acceptance_criteria: []
|
|
133
|
+
---
|
|
134
|
+
<!-- SCAFFOLD-STUB: fill all sections and delete this line before sign-off -->
|
|
135
|
+
|
|
136
|
+
# {{ID}} {{TITLE}}
|
|
137
|
+
|
|
138
|
+
## Summary
|
|
139
|
+
|
|
140
|
+
One paragraph: what the feature is and who it's for.
|
|
141
|
+
|
|
142
|
+
## User Stories {#user-stories}
|
|
143
|
+
|
|
144
|
+
- **US-1** [planned] As a *role*, I want *capability* so that *value*.
|
|
145
|
+
|
|
146
|
+
## Acceptance Criteria
|
|
147
|
+
|
|
148
|
+
Authoritative copy is the \`acceptance_criteria:\` frontmatter.
|
|
149
|
+
|
|
150
|
+
## Test Plan
|
|
151
|
+
|
|
152
|
+
How each AC is proven.
|
|
153
|
+
`;
|
|
154
|
+
const SPEC_TEMPLATE_LITE = `---
|
|
155
|
+
id: {{ID}}
|
|
156
|
+
title: "{{TITLE}}"
|
|
157
|
+
core: {{CORE}}
|
|
158
|
+
status: specification
|
|
159
|
+
version: "1.0"
|
|
160
|
+
pipeline_status: stub
|
|
161
|
+
acceptance_criteria: []
|
|
162
|
+
---
|
|
163
|
+
<!-- SCAFFOLD-STUB: fill all sections and delete this line before sign-off -->
|
|
164
|
+
|
|
165
|
+
# {{ID}} {{TITLE}}
|
|
166
|
+
|
|
167
|
+
## Summary
|
|
168
|
+
|
|
169
|
+
What changes and why.
|
|
170
|
+
`;
|
|
171
|
+
const PLAN_TEMPLATE = `# {{ID}} {{TITLE}} — Implementation Plan
|
|
172
|
+
|
|
173
|
+
## Phases
|
|
174
|
+
|
|
175
|
+
1. …
|
|
176
|
+
`;
|
|
177
|
+
const TASKS_TEMPLATE = `# {{ID}} {{TITLE}} — Tasks
|
|
178
|
+
|
|
179
|
+
- [ ] T1 First task
|
|
180
|
+
`;
|
|
181
|
+
const SPEC_GUIDE = `# Spec Guide
|
|
182
|
+
|
|
183
|
+
A decision tree for authoring specs. Replace this stub with your conventions; its
|
|
184
|
+
presence satisfies \`eos-spec init\`.
|
|
185
|
+
`;
|
|
186
|
+
const TEMPLATE_INDEX = `# Template Index
|
|
187
|
+
|
|
188
|
+
Which template to use when. Replace this stub with your selection guide; its
|
|
189
|
+
presence satisfies \`eos-spec init\`.
|
|
190
|
+
`;
|
|
191
|
+
/**
|
|
192
|
+
* Template files written under \`specs/_templates/\` by \`init --scaffold\`, verbatim
|
|
193
|
+
* (placeholders intact). \`rel\` is relative to repo root.
|
|
194
|
+
*/
|
|
195
|
+
export const SCAFFOLD_TEMPLATE_FILES = [
|
|
196
|
+
{ rel: 'specs/_templates/SPEC_TEMPLATE.md', content: SPEC_TEMPLATE },
|
|
197
|
+
{ rel: 'specs/_templates/SPEC_TEMPLATE_LITE.md', content: SPEC_TEMPLATE_LITE },
|
|
198
|
+
{ rel: 'specs/_templates/PLAN_TEMPLATE.md', content: PLAN_TEMPLATE },
|
|
199
|
+
{ rel: 'specs/_templates/TASKS_TEMPLATE.md', content: TASKS_TEMPLATE },
|
|
200
|
+
{ rel: 'specs/_templates/SPEC_GUIDE.md', content: SPEC_GUIDE },
|
|
201
|
+
{ rel: 'specs/_templates/TEMPLATE_INDEX.md', content: TEMPLATE_INDEX },
|
|
202
|
+
];
|
|
203
|
+
//# sourceMappingURL=scaffold-templates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold-templates.js","sourceRoot":"","sources":["../../src/lib/scaffold-templates.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AAExD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,WAAmB;IACnD,OAAO;;;;gBAIO,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6F1B,CAAC;AACF,CAAC;AAED,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA+BrB,CAAC;AAEF,MAAM,kBAAkB,GAAG;;;;;;;;;;;;;;;;CAgB1B,CAAC;AAEF,MAAM,aAAa,GAAG;;;;;CAKrB,CAAC;AAEF,MAAM,cAAc,GAAG;;;CAGtB,CAAC;AAEF,MAAM,UAAU,GAAG;;;;CAIlB,CAAC;AAEF,MAAM,cAAc,GAAG;;;;CAItB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAoD;IACtF,EAAE,GAAG,EAAE,mCAAmC,EAAE,OAAO,EAAE,aAAa,EAAE;IACpE,EAAE,GAAG,EAAE,wCAAwC,EAAE,OAAO,EAAE,kBAAkB,EAAE;IAC9E,EAAE,GAAG,EAAE,mCAAmC,EAAE,OAAO,EAAE,aAAa,EAAE;IACpE,EAAE,GAAG,EAAE,oCAAoC,EAAE,OAAO,EAAE,cAAc,EAAE;IACtE,EAAE,GAAG,EAAE,gCAAgC,EAAE,OAAO,EAAE,UAAU,EAAE;IAC9D,EAAE,GAAG,EAAE,oCAAoC,EAAE,OAAO,EAAE,cAAc,EAAE;CACvE,CAAC"}
|
package/dist/lib/spec-pure.js
CHANGED
|
@@ -20,6 +20,28 @@ import { acStatusCounts, allAcceptanceCriteriaTerminal } from './requirements.js
|
|
|
20
20
|
export const REGULATED_CORES = new Set(['cl', 'pm', 'hr', 'rh', 'gr']);
|
|
21
21
|
/** The marker the generator emits for an AC-less spec. */
|
|
22
22
|
const GENERATED_NO_AC_MARKER = 'no acceptance_criteria — run encore-spec-ac-draft first';
|
|
23
|
+
/** Keywords that mark a spec as carrying sensitive data — PHI/PII/billing/
|
|
24
|
+
* credentialing. The `/spec-pipeline` step-3b compliance gate fires on these
|
|
25
|
+
* mentions in ANY core (not just the regulated `cl/pm/hr/rh/gr` set), so the
|
|
26
|
+
* engine must detect them to gate `hasComplianceForSensitive` at parity with the
|
|
27
|
+
* command prose. Matched at word boundaries, case-insensitively, over frontmatter
|
|
28
|
+
* + body. Kept to high-signal regime tokens so an incidental mention never trips
|
|
29
|
+
* it; a spec can also opt in explicitly via a `<!-- sensitive -->`/`<!-- sensitive: -->`
|
|
30
|
+
* marker or a `sensitive`/`phi`/`pii`/`billing`/`credentialing` tag. */
|
|
31
|
+
const SENSITIVE_KEYWORD_RE = /\b(PHI|PII|protected health information|personally identifiable information|billing|claims?|reimbursement|remittance advice|credentialing|payer enrollment|HIPAA|42 CFR Part 2)\b/i;
|
|
32
|
+
/** True when the spec text (frontmatter + body) signals sensitive data: a
|
|
33
|
+
* high-signal regime keyword, an explicit `<!-- sensitive -->` marker, or a
|
|
34
|
+
* `sensitive`/`phi`/`pii`/`billing`/`credentialing` tag. Pure (operates on the raw
|
|
35
|
+
* spec text + the parsed `tags` array). Independent of `isRegulated` — a non-
|
|
36
|
+
* regulated FA billing or PF credentialing spec is `isSensitive` without being a
|
|
37
|
+
* regulated core, which is exactly the parity gap Finding A item 2 names. */
|
|
38
|
+
function detectSensitive(text, tags) {
|
|
39
|
+
if (/<!--\s*sensitive\s*(?::[^>]*)?-->/i.test(text))
|
|
40
|
+
return true;
|
|
41
|
+
if (tags.some((t) => /^(sensitive|phi|pii|billing|credentialing)$/i.test(String(t).trim())))
|
|
42
|
+
return true;
|
|
43
|
+
return SENSITIVE_KEYWORD_RE.test(text);
|
|
44
|
+
}
|
|
23
45
|
/** True when a generated test source has ≥1 ACTIVE `test(` block (not `test.fixme`/
|
|
24
46
|
* `test.describe`) and is not an AC-less placeholder. Pure (operates on source text). */
|
|
25
47
|
export function hasActiveGeneratedTestSource(source) {
|
|
@@ -41,6 +63,7 @@ export function deriveSignalsFromText(core, text, flags = {}) {
|
|
|
41
63
|
const hasUserStoriesSection = /^#{1,3}\s+User Stories\b/im.test(text);
|
|
42
64
|
const affectedFiles = Array.isArray(fm.affected_files) ? fm.affected_files.map(String) : [];
|
|
43
65
|
const uiAffectedFiles = affectedFiles.some((f) => /\/(components|pages|wizards)\//.test(f) || f.endsWith('.tsx'));
|
|
66
|
+
const tags = Array.isArray(fm.tags) ? fm.tags.map(String) : [];
|
|
44
67
|
return {
|
|
45
68
|
isRegulated: REGULATED_CORES.has(core.toLowerCase()),
|
|
46
69
|
pipelineStatus: typeof fm.pipeline_status === 'string' ? fm.pipeline_status : undefined,
|
|
@@ -60,11 +83,22 @@ export function deriveSignalsFromText(core, text, flags = {}) {
|
|
|
60
83
|
hasDocshots: docshotImageExists || /-docs-shots\.spec\.ts/.test(text) || /<!--\s*docshots:/i.test(text),
|
|
61
84
|
hasHealSignoff: /<!--\s*heal-verified:/i.test(text),
|
|
62
85
|
hasUiGateWaiver: /<!--\s*ui-gate-waived:/i.test(text),
|
|
86
|
+
// PHI/PII/billing/credentialing signal — drives the `hasComplianceForSensitive`
|
|
87
|
+
// gate for NON-regulated cores too (Finding A item 2). Content-derived, so it
|
|
88
|
+
// needs no fs flag; stays in this pure helper.
|
|
89
|
+
isSensitive: detectSensitive(text, tags),
|
|
90
|
+
// Re-validation after spec-review (Finding A item 1): the `/spec-pipeline` step-5
|
|
91
|
+
// re-run of validate-spec, recorded as a `<!-- revalidated-after-review: <date> -->`
|
|
92
|
+
// marker parallel to the other sign-off markers.
|
|
93
|
+
hasReValidationAfterReview: /<!--\s*revalidated-after-review:/i.test(text),
|
|
63
94
|
isCreateWizardSpec,
|
|
64
95
|
hasSubmitE2e: submitE2eProvesPersist || /<!--\s*submit-e2e-waived:/i.test(text),
|
|
65
96
|
blockedBy: collectSpecIds(fm.blocked_by),
|
|
66
97
|
hasVerificationSection: /^#{1,3}\s+Verification\b/im.test(text),
|
|
67
98
|
acStatus: acStatusCounts(fm.acceptance_criteria),
|
|
99
|
+
// WEB-51: a recorded demo-proof artifact pointer. Content-derived (no fs flag),
|
|
100
|
+
// so it stays in this pure helper alongside the other frontmatter signals.
|
|
101
|
+
hasProofArtifact: typeof fm.proof === 'string' && fm.proof.trim() !== '',
|
|
68
102
|
};
|
|
69
103
|
}
|
|
70
104
|
// ── pure path classification (the fs-free half of specs.ts's directory walk) ──
|
|
@@ -112,7 +146,16 @@ function specBasename(path) {
|
|
|
112
146
|
* (epic #300, Wave-1 G3).
|
|
113
147
|
*/
|
|
114
148
|
export function extractSpecId(filename, core) {
|
|
115
|
-
|
|
149
|
+
// The enhancement suffix carries a trailing `(?![A-Za-z0-9])` boundary so the
|
|
150
|
+
// `E\d+` / `P\d+` alternatives only fire on a COMPLETE id segment, never the leading
|
|
151
|
+
// fragment of an ordinary slug word that happens to begin with `e`/`p`. Without it,
|
|
152
|
+
// `WEB-05-e2e-walking-skeleton` parsed as `WEB-05-e2` (the `E\d+` branch ate `-e2` of
|
|
153
|
+
// `e2e`), so the file counted in `listSpecs` but `findSpec`'s id-equality filter never
|
|
154
|
+
// matched it — the spec silently escaped every per-spec gate (issue #14). In every valid
|
|
155
|
+
// id the enhancement is followed by `-slug` or end-of-name, so the boundary is a no-op
|
|
156
|
+
// for real suffixes (`CE-03-E1`, `HR-09-P5`, `PM-15-P2-EN-01`, `LO-01-EN-1`) and only
|
|
157
|
+
// rejects the prefix-of-a-longer-alnum-run over-match.
|
|
158
|
+
const re = new RegExp(`^(${escapeForRegExp(core)}(?:-[A-Z]{1,4})?-\\d+(?:\\.\\d+)?(?:-(?:EN-\\d+|E\\d+|P\\d+(?:\\.\\d+)?(?:-EN-\\d+)?)(?![A-Za-z0-9]))?)`, 'i');
|
|
116
159
|
const match = re.exec(specBasename(filename));
|
|
117
160
|
return match ? match[1] : null;
|
|
118
161
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"spec-pure.js","sourceRoot":"","sources":["../../src/lib/spec-pure.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"spec-pure.js","sourceRoot":"","sources":["../../src/lib/spec-pure.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/specs.d.ts
CHANGED
|
@@ -59,6 +59,18 @@ export type SpecSignals = {
|
|
|
59
59
|
* `eos-spec signoff --type ui-gate-waived`. Documented escape for the C1
|
|
60
60
|
* UI-evidence gate (e.g. a backend spec that `isUiBearing` false-positives on). */
|
|
61
61
|
hasUiGateWaiver: boolean;
|
|
62
|
+
/** Phase 1 (Finding A item 2): the spec carries a PHI/PII/billing/credentialing
|
|
63
|
+
* signal (keyword, `<!-- sensitive -->` marker, or `sensitive`/`phi`/`pii`/
|
|
64
|
+
* `billing`/`credentialing` tag). Generalizes the regulated-core-only compliance
|
|
65
|
+
* gate to sensitive NON-regulated cores via `hasComplianceForSensitive`. Optional
|
|
66
|
+
* on the type for signal-shape stability across the captured parity fixtures (which
|
|
67
|
+
* predate it); always populated by deriveSignals. */
|
|
68
|
+
isSensitive?: boolean;
|
|
69
|
+
/** Phase 1 (Finding A item 1): a `<!-- revalidated-after-review: <date> -->` marker
|
|
70
|
+
* is present — the `/spec-pipeline` step-5 re-run of validate-spec after spec-review
|
|
71
|
+
* auto-applied edits. Gates `hasReValidationAfterReview` under `next --strict`.
|
|
72
|
+
* Optional for fixture-shape stability; always populated by deriveSignals. */
|
|
73
|
+
hasReValidationAfterReview?: boolean;
|
|
62
74
|
/** Phase 3 (#1185): the spec is a kind:'create' wizard per the generated
|
|
63
75
|
* wizard-create-specs bridge. Gates the submit→DB E2E completion check. */
|
|
64
76
|
isCreateWizardSpec?: boolean;
|
|
@@ -78,6 +90,11 @@ export type SpecSignals = {
|
|
|
78
90
|
* frontmatter — the typed AC model the `audit` command consumes (#174). Optional on
|
|
79
91
|
* the type for signal-shape stability; always populated by deriveSignals. */
|
|
80
92
|
acStatus?: AcStatusCounts;
|
|
93
|
+
/** A `proof:` frontmatter pointer to a recorded demo-proof artifact is present
|
|
94
|
+
* (WEB-51). The `audit` command warns (warn-first, non-gating) when a UI-bearing
|
|
95
|
+
* spec at a done status lacks it. Optional for signal-shape stability; always
|
|
96
|
+
* populated by deriveSignals. */
|
|
97
|
+
hasProofArtifact?: boolean;
|
|
81
98
|
};
|
|
82
99
|
export type SpecFile = {
|
|
83
100
|
id: string;
|