etymd 0.14.0 → 0.16.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 +52 -16
- package/README.md +114 -47
- package/dist/{approve-QDOH2E7V.js → approve-K5FFTPA4.js} +2 -2
- package/dist/{audit-42OHF7ON.js → audit-HBNXNGD6.js} +5 -4
- package/dist/{brief-ZUQK3CFL.js → brief-DOQ2DQEG.js} +2 -2
- package/dist/{fleet-F3XDEDCV.js → chunk-ANXGT7V3.js} +431 -466
- package/dist/{chunk-HWC6PKJM.js → chunk-EJM47PIF.js} +1 -1
- package/dist/{chunk-PAMWS665.js → chunk-FKDT4RBP.js} +2 -1
- package/dist/{chunk-UFNETE6P.js → chunk-OKJ3RGJB.js} +1 -1
- package/dist/{chunk-LT7JMVV3.js → chunk-UV3YIBDW.js} +43 -730
- package/dist/{chunk-623W6KVC.js → chunk-UYCGP5BS.js} +1 -1
- package/dist/chunk-Y4E6ERCM.js +783 -0
- package/dist/cli.js +78 -22
- package/dist/{doctor-CE5SD4JW.js → doctor-X6XAGKV7.js} +5 -4
- package/dist/fleet-UEFLKIRI.js +489 -0
- package/dist/{gates-F4YPKWJR.js → gates-NVWWKMT2.js} +3 -3
- package/dist/{generate-KEX75XNG.js → generate-YEARCSHW.js} +1 -1
- package/dist/index.d.ts +301 -20
- package/dist/index.js +958 -233
- package/dist/{init-AHA7VRRI.js → init-Z5O2WVRJ.js} +3 -3
- package/dist/premise-4QRU7LRI.js +368 -0
- package/dist/propose-IKE4CUIM.js +252 -0
- package/dist/scan-64Z6SNYF.js +5 -0
- package/dist/{scan-TVX3FKK4.js → scan-H3NF5IV5.js} +2 -2
- package/package.json +5 -5
- package/dist/scan-QRTH6HAP.js +0 -5
package/dist/index.d.ts
CHANGED
|
@@ -464,12 +464,12 @@ interface AuditOptions {
|
|
|
464
464
|
persistLedger?: boolean;
|
|
465
465
|
/**
|
|
466
466
|
* Fleet: the audited root is READ-ONLY — write nothing into it, not even the scan cache
|
|
467
|
-
* where `.etymd` already exists there. A
|
|
467
|
+
* where `.etymd` already exists there. A guarded worktree is never written, regardless of flags.
|
|
468
468
|
*/
|
|
469
469
|
readOnlyRoot?: boolean;
|
|
470
470
|
/**
|
|
471
|
-
* Fleet: read/write the ledger at this root instead of the audited one.
|
|
472
|
-
* under the manifest's `
|
|
471
|
+
* Fleet: read/write the ledger at this root instead of the audited one. Guarded findings persist
|
|
472
|
+
* under the manifest's `guarded/<name>/`, never inside the guarded worktree.
|
|
473
473
|
*/
|
|
474
474
|
ledgerRoot?: string;
|
|
475
475
|
/** Fleet: per-entry state-budget overlay (registry `staleAfterDays` / `stateBudget`). */
|
|
@@ -490,11 +490,11 @@ interface AuditResult {
|
|
|
490
490
|
}
|
|
491
491
|
declare function runAudit(root: string, opts?: AuditOptions): Promise<AuditResult>;
|
|
492
492
|
|
|
493
|
-
type FleetProfile = "personal" | "
|
|
493
|
+
type FleetProfile = "personal" | "guarded";
|
|
494
494
|
/**
|
|
495
495
|
* How exposed an entry's history is, or could plausibly become. A SAFETY PREDICATE, not a label:
|
|
496
496
|
* it decides whether content screening applies, so absence must never read as the permissive
|
|
497
|
-
* answer. `checkManifest` treats an undeclared non-
|
|
497
|
+
* answer. `checkManifest` treats an undeclared non-guarded entry as a finding — a repo published
|
|
498
498
|
* without ever answering the question is exactly the case a default would hide.
|
|
499
499
|
*
|
|
500
500
|
* `public-repo` already public — outside-contribution surface.
|
|
@@ -503,7 +503,7 @@ type FleetProfile = "personal" | "corp";
|
|
|
503
503
|
* not the visibility flip.
|
|
504
504
|
* `private` not destined to be published. An ANSWER, not the absence of one.
|
|
505
505
|
*
|
|
506
|
-
*
|
|
506
|
+
* Guarded entries do not carry it — `profile: "guarded"` implies the answer (machine-pinned, never
|
|
507
507
|
* publishable), so requiring it there would be ceremony.
|
|
508
508
|
*/
|
|
509
509
|
type FleetTrust = "public-repo" | "public-bound" | "private";
|
|
@@ -524,6 +524,12 @@ interface FleetContract {
|
|
|
524
524
|
state?: string;
|
|
525
525
|
decisions?: string;
|
|
526
526
|
goals?: string;
|
|
527
|
+
/**
|
|
528
|
+
* The project's milestones file (`MILESTONES.md` by convention), rolled up by `etymd fleet
|
|
529
|
+
* board`; its shape is checked by the sweep. `"none"` declares the project deliberately
|
|
530
|
+
* carries no milestones (a state, not a gap).
|
|
531
|
+
*/
|
|
532
|
+
milestones?: string;
|
|
527
533
|
/** `"none"` = the contract file is legitimately absent (a declared state, not a gap). */
|
|
528
534
|
placement?: string;
|
|
529
535
|
}
|
|
@@ -538,7 +544,7 @@ interface FleetEntry {
|
|
|
538
544
|
upstream?: string;
|
|
539
545
|
/**
|
|
540
546
|
* How exposed this entry is — see {@link FleetTrust}. `"public-repo"` marks an
|
|
541
|
-
* outside-contribution surface (hygiene needles apply). Undeclared on a non-
|
|
547
|
+
* outside-contribution surface (hygiene needles apply). Undeclared on a non-guarded entry is a
|
|
542
548
|
* `fleet check` finding, never a silent "private".
|
|
543
549
|
*/
|
|
544
550
|
trust?: FleetTrust;
|
|
@@ -573,14 +579,14 @@ interface FleetManifest {
|
|
|
573
579
|
shape: "registry" | "corpus";
|
|
574
580
|
/** Absolute path of the tracked manifest file. */
|
|
575
581
|
manifestPath: string;
|
|
576
|
-
/** Its directory —
|
|
582
|
+
/** Its directory — guarded persistence roots and the sweep delta file live beside it. */
|
|
577
583
|
dir: string;
|
|
578
584
|
/** Resolved absolute fleet root (registry shape), when declared. */
|
|
579
585
|
root?: string;
|
|
580
586
|
/** Fleet-wide orientation root, when the manifest declares one. Absent = this fleet has none. */
|
|
581
587
|
orientation?: FleetOrientation;
|
|
582
588
|
machineProfile?: FleetProfile;
|
|
583
|
-
|
|
589
|
+
guardedHosts: string[];
|
|
584
590
|
labels: Record<string, string>;
|
|
585
591
|
localDirs: Record<string, string>;
|
|
586
592
|
/** Absolute path where the gitignored local sibling is expected. */
|
|
@@ -605,18 +611,18 @@ declare const FLEET_JSON_SCHEMA = "fleet-experimental-0.2";
|
|
|
605
611
|
interface FleetSweepOptions {
|
|
606
612
|
/** Restrict to these registered names (unknown names throw — a typo must not skip silently). */
|
|
607
613
|
only?: string[];
|
|
608
|
-
profile?: "personal" | "
|
|
614
|
+
profile?: "personal" | "guarded";
|
|
609
615
|
/** Truth lenses only per repo (the doctor subset). */
|
|
610
616
|
kind?: LensKind;
|
|
611
617
|
/**
|
|
612
618
|
* Persist per-repo ledgers — ONLY for personal-profile entries that already carry `.etymd`.
|
|
613
|
-
* The sweep never creates `.etymd` anywhere, and
|
|
619
|
+
* The sweep never creates `.etymd` anywhere, and guarded worktrees are never written at all.
|
|
614
620
|
*/
|
|
615
621
|
persistLedgers?: boolean;
|
|
616
622
|
}
|
|
617
623
|
interface FleetProjectSweep {
|
|
618
624
|
name: string;
|
|
619
|
-
profile: "personal" | "
|
|
625
|
+
profile: "personal" | "guarded";
|
|
620
626
|
kind?: string;
|
|
621
627
|
resolvedRoot?: string;
|
|
622
628
|
/** Why this entry could not be audited — mirrored into `outOfScope`. */
|
|
@@ -648,15 +654,15 @@ interface RecurringClass {
|
|
|
648
654
|
/** The `<lens>/<class>` id prefix — minted by the engine's lenses, identical across repos. */
|
|
649
655
|
classId: string;
|
|
650
656
|
tier: FindingTier;
|
|
651
|
-
/** Project names (
|
|
657
|
+
/** Project names (guarded entries by alias) where the class is currently open. */
|
|
652
658
|
projects: string[];
|
|
653
659
|
}
|
|
654
660
|
/**
|
|
655
|
-
* Where a
|
|
661
|
+
* Where a guarded entry's audit state persists: beside the manifest, never in the worktree.
|
|
656
662
|
* Belt-and-braces to the loader's safe-name rule: a name that resolves anywhere but directly
|
|
657
|
-
* under `<dir>/
|
|
663
|
+
* under `<dir>/guarded/` is refused — the manifest can lie, and a lie must never steer a write.
|
|
658
664
|
*/
|
|
659
|
-
declare function
|
|
665
|
+
declare function guardedPersistenceRoot(manifest: FleetManifest, name: string): string;
|
|
660
666
|
/**
|
|
661
667
|
* Validate the manifest pair itself: parse problems, dangling mappings (the live ghost-entry
|
|
662
668
|
* class), duplicate names, privacy leaks, dead links, machine paths. Pure manifest truth —
|
|
@@ -673,12 +679,94 @@ declare function collectWallFindings(manifest: FleetManifest): Promise<{
|
|
|
673
679
|
}>;
|
|
674
680
|
/**
|
|
675
681
|
* The fleet sweep: one read-only audit per resolved entry + the fleet-scope wall checks.
|
|
676
|
-
* Invariants (each pinned by test): never creates `.etymd` anywhere; never writes into a
|
|
682
|
+
* Invariants (each pinned by test): never creates `.etymd` anywhere; never writes into a guarded
|
|
677
683
|
* worktree regardless of flags or a stray `.etymd` there; unresolvable entries land in
|
|
678
684
|
* `outOfScope` with a disclosure, never a silent skip.
|
|
679
685
|
*/
|
|
680
686
|
declare function sweepFleet(manifest: FleetManifest, opts?: FleetSweepOptions): Promise<FleetSweepResult>;
|
|
681
687
|
|
|
688
|
+
/**
|
|
689
|
+
* `etymd propose` — the scoring step between the sweep and a filed proposal.
|
|
690
|
+
*
|
|
691
|
+
* The sweep already mints everything a proposal needs (every finding carries an action, an
|
|
692
|
+
* effort and a confidence; `recurringClasses` names the classes open in ≥2 projects). This
|
|
693
|
+
* module adds the two things that were missing: a rubric the FLEET authors (the tool ships
|
|
694
|
+
* none — with no rubric there is nothing to run) and a stable record shape (`proposal/1`)
|
|
695
|
+
* a planning surface can file mechanically.
|
|
696
|
+
*
|
|
697
|
+
* Everything here is a pure function of its inputs — no clocks, no randomness — so the same
|
|
698
|
+
* sweep plus the same rubric yields byte-identical output, and a filed proposal can be
|
|
699
|
+
* re-derived and compared later. Decision record: docs/decisions/012.
|
|
700
|
+
*/
|
|
701
|
+
/** The record schema marker — experimental through 0.2.x with the rest of the fleet family. */
|
|
702
|
+
declare const PROPOSAL_SCHEMA = "proposal/1";
|
|
703
|
+
/**
|
|
704
|
+
* The criteria the tool can compute, each mapped to a 1–3 value. The vocabulary is closed: a
|
|
705
|
+
* rubric line naming anything else is refused, because a criterion this tool cannot derive
|
|
706
|
+
* mechanically would be an opinion wearing a number — the exact product anti-pattern. The
|
|
707
|
+
* WEIGHTS are the fleet's; the tool imposes none.
|
|
708
|
+
*/
|
|
709
|
+
declare const RUBRIC_CRITERIA: readonly ["severity", "economy", "confidence", "breadth"];
|
|
710
|
+
type RubricCriterion = (typeof RUBRIC_CRITERIA)[number];
|
|
711
|
+
interface RubricLine {
|
|
712
|
+
criterion: RubricCriterion;
|
|
713
|
+
weight: number;
|
|
714
|
+
}
|
|
715
|
+
interface Rubric {
|
|
716
|
+
lines: RubricLine[];
|
|
717
|
+
}
|
|
718
|
+
/**
|
|
719
|
+
* Parse a rubric file: labeled lines, one criterion per line (`criterion: <weight>`), `#`
|
|
720
|
+
* comments and blanks ignored. The line is the unit of refusal — unknown criterion, malformed
|
|
721
|
+
* line, duplicate criterion, or a rubric with no criteria at all each name their line (or the
|
|
722
|
+
* file), never a silent skip and never a default weight.
|
|
723
|
+
*/
|
|
724
|
+
declare function parseRubric(text: string, file: string): Rubric;
|
|
725
|
+
interface MatchedLine {
|
|
726
|
+
criterion: RubricCriterion;
|
|
727
|
+
weight: number;
|
|
728
|
+
/** The computed 1–3 value — carried beside the weight so the score is auditable. */
|
|
729
|
+
value: number;
|
|
730
|
+
}
|
|
731
|
+
interface Implications {
|
|
732
|
+
projects: string[];
|
|
733
|
+
files: string[];
|
|
734
|
+
gates: string[];
|
|
735
|
+
reversibility: "regenerable" | "git-reversible" | "undetermined";
|
|
736
|
+
}
|
|
737
|
+
interface Proposal {
|
|
738
|
+
id: string;
|
|
739
|
+
schema: typeof PROPOSAL_SCHEMA;
|
|
740
|
+
class: string;
|
|
741
|
+
kind: "finding" | "class";
|
|
742
|
+
projects: string[];
|
|
743
|
+
action: string;
|
|
744
|
+
effort: Effort;
|
|
745
|
+
confidence: Confidence;
|
|
746
|
+
score: number;
|
|
747
|
+
matched: MatchedLine[];
|
|
748
|
+
implications: Implications;
|
|
749
|
+
}
|
|
750
|
+
interface ProposeResult {
|
|
751
|
+
schema: typeof PROPOSAL_SCHEMA;
|
|
752
|
+
manifest: string;
|
|
753
|
+
rubric: string;
|
|
754
|
+
criteria: RubricLine[];
|
|
755
|
+
proposals: Proposal[];
|
|
756
|
+
disclosures: string[];
|
|
757
|
+
}
|
|
758
|
+
/**
|
|
759
|
+
* Build the proposals from a sweep result: every `kind: "improvement"` finding from every
|
|
760
|
+
* personal project, plus every recurring class recomputed over personal projects only. Guarded
|
|
761
|
+
* entries are excluded from the output entire (their findings, and their names inside class
|
|
762
|
+
* breadth) — a guarded improvement is the guarded side's backlog, not this fleet's proposal queue —
|
|
763
|
+
* and their exclusion is disclosed by name so absence is a stated policy, never a hole.
|
|
764
|
+
*/
|
|
765
|
+
declare function buildProposals(sweep: {
|
|
766
|
+
manifest: string;
|
|
767
|
+
projects: FleetProjectSweep[];
|
|
768
|
+
}, rubricName: string, rubric: Rubric): ProposeResult;
|
|
769
|
+
|
|
682
770
|
/**
|
|
683
771
|
* The truth lens: does what the instruction files CLAIM still hold against the actual repo?
|
|
684
772
|
* Commands must exist as scripts, paths must exist on disk, files must agree on the package
|
|
@@ -686,6 +774,188 @@ declare function sweepFleet(manifest: FleetManifest, opts?: FleetSweepOptions):
|
|
|
686
774
|
*/
|
|
687
775
|
declare const instructionTruthLens: Lens;
|
|
688
776
|
|
|
777
|
+
/** Everything a truth check needs from the repo, resolved once per run. */
|
|
778
|
+
interface TruthEnv {
|
|
779
|
+
root: string;
|
|
780
|
+
facts: ProjectFacts;
|
|
781
|
+
/** Package scripts across the root and every workspace manifest. */
|
|
782
|
+
knownScripts: Set<string>;
|
|
783
|
+
nodeModulesInstalled: boolean;
|
|
784
|
+
/** A manifest exists somewhere, so a script claim is checkable even without an install. */
|
|
785
|
+
manifestExists: boolean;
|
|
786
|
+
/** The root plus every workspace package dir — where claims are resolved. */
|
|
787
|
+
bases: string[];
|
|
788
|
+
/** A repo-relative claim resolves in the root, any workspace package, or their src/ scripts/. */
|
|
789
|
+
pathResolves(claim: string): Promise<boolean>;
|
|
790
|
+
/** `yarn X` / `pnpm X` may legitimately run an installed node_modules/.bin binary. */
|
|
791
|
+
binResolves(name: string): Promise<boolean>;
|
|
792
|
+
}
|
|
793
|
+
declare function buildTruthEnv(root: string, facts: ProjectFacts): Promise<TruthEnv>;
|
|
794
|
+
/** Skip-class tallies — every class a check declines to accuse is counted, then disclosed. */
|
|
795
|
+
interface ClaimCounters {
|
|
796
|
+
filteredSkipped: number;
|
|
797
|
+
tildeSkipped: number;
|
|
798
|
+
binaryResolved: number;
|
|
799
|
+
unverifiableCommands: number;
|
|
800
|
+
gitignoredSkipped: number;
|
|
801
|
+
prospectiveSkipped: number;
|
|
802
|
+
placeholderSkipped: number;
|
|
803
|
+
/** Decision references naming another record (a fleet-level ledger) — not this repo's. */
|
|
804
|
+
qualifiedRefsSkipped: number;
|
|
805
|
+
/** Decision references with no `## D-NNN` ledger to resolve against. */
|
|
806
|
+
unresolvableRefs: number;
|
|
807
|
+
/** Path claims whose every mention sits behind a namespace prefix (`pc:`) — another repo's. */
|
|
808
|
+
namespacedSkipped: number;
|
|
809
|
+
/** Missing paths starting at no directory of this repo — quoted from elsewhere (task only). */
|
|
810
|
+
outsideRepoSkipped: number;
|
|
811
|
+
}
|
|
812
|
+
declare function emptyCounters(): ClaimCounters;
|
|
813
|
+
/**
|
|
814
|
+
* One thing a check looked for, and what it found. `null` = could not be checked from the repo
|
|
815
|
+
* (counted and disclosed), never a guess. The honest-coverage half of a report: what was
|
|
816
|
+
* examined, not only what failed.
|
|
817
|
+
*/
|
|
818
|
+
interface ExaminedClaim {
|
|
819
|
+
kind: "script" | "path" | "doc" | "decision";
|
|
820
|
+
value: string;
|
|
821
|
+
exists: boolean | null;
|
|
822
|
+
}
|
|
823
|
+
/** A piece of text making claims about the repo: an instruction file, a state doc, a task. */
|
|
824
|
+
interface ClaimText {
|
|
825
|
+
/** Repo-relative path, or a label such as `task` — becomes part of every finding id. */
|
|
826
|
+
path: string;
|
|
827
|
+
text: string;
|
|
828
|
+
}
|
|
829
|
+
interface TextClaimsOptions {
|
|
830
|
+
/** The lens the findings report under (`instruction-truth`, `premise`). */
|
|
831
|
+
lensId: string;
|
|
832
|
+
/** How the text is named in a claim sentence — a file path, or "The task". */
|
|
833
|
+
subject?: string;
|
|
834
|
+
/**
|
|
835
|
+
* A missing path is `gap` for an instruction file (a dead reference among many) and `risk` for
|
|
836
|
+
* a task (the task is ABOUT the path — an agent acting on it does the wrong thing).
|
|
837
|
+
*/
|
|
838
|
+
missingPathTier: FindingTier;
|
|
839
|
+
maxPathFindings: number;
|
|
840
|
+
whyCommand?: string;
|
|
841
|
+
actionCommand?: string;
|
|
842
|
+
whyPath?: string;
|
|
843
|
+
actionPath?: string;
|
|
844
|
+
/**
|
|
845
|
+
* Directories a missing path may start from and still be plausibly repo-relative — the root,
|
|
846
|
+
* workspace packages, and their src/ scripts/. Supplied by the task surface (`etymd premise`)
|
|
847
|
+
* only: a task quoting a path from ANOTHER repository (a clone in a scratchpad) starts where
|
|
848
|
+
* no directory of this repo does, and its absence here proves nothing. Instruction files keep
|
|
849
|
+
* the stricter reading — their references are written against this repo.
|
|
850
|
+
*/
|
|
851
|
+
rootedFirstSegments?: ReadonlySet<string>;
|
|
852
|
+
/**
|
|
853
|
+
* Read namespace-prefixed path mentions (`pc: `src/x.ts``) as another repo's tree — the task
|
|
854
|
+
* surface only; instruction files keep every backticked span as a claim of this repo.
|
|
855
|
+
*/
|
|
856
|
+
treatNamespacedPrefixes?: boolean;
|
|
857
|
+
}
|
|
858
|
+
interface TextClaimsResult {
|
|
859
|
+
findings: Finding[];
|
|
860
|
+
disclosures: string[];
|
|
861
|
+
/** Every script and path claim the text made, found or not. */
|
|
862
|
+
examined: ExaminedClaim[];
|
|
863
|
+
}
|
|
864
|
+
/**
|
|
865
|
+
* Command and path claims in one text, verified against the repo. Precision over recall: every
|
|
866
|
+
* class it declines to accuse is counted in `counters` for the caller to disclose.
|
|
867
|
+
*/
|
|
868
|
+
declare function checkTextClaims(env: TruthEnv, file: ClaimText, opts: TextClaimsOptions, counters: ClaimCounters): Promise<TextClaimsResult>;
|
|
869
|
+
interface RefsResult {
|
|
870
|
+
findings: Finding[];
|
|
871
|
+
examined: ExaminedClaim[];
|
|
872
|
+
}
|
|
873
|
+
/** Cross-references to well-known docs (AGENTS.md, CLAUDE.md, …) must resolve to real files. */
|
|
874
|
+
declare function checkDocRefs(env: TruthEnv, file: ClaimText, lensId: string, counters: ClaimCounters, subject?: string): Promise<RefsResult>;
|
|
875
|
+
/** The repo's own decision record: every `## D-NNN` id, and which files carried them. */
|
|
876
|
+
interface DecisionLedger {
|
|
877
|
+
/** Null when no decisions file with parseable `## D-NNN` entries exists. */
|
|
878
|
+
ids: Set<number> | null;
|
|
879
|
+
sources: string[];
|
|
880
|
+
}
|
|
881
|
+
declare function loadDecisionLedger(root: string, facts: ProjectFacts): Promise<DecisionLedger>;
|
|
882
|
+
interface DecisionRefsOptions {
|
|
883
|
+
lensId: string;
|
|
884
|
+
/** How the text is named in a claim sentence — a file path, or "The task". */
|
|
885
|
+
subject?: string;
|
|
886
|
+
why?: string;
|
|
887
|
+
action?: string;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* `D-NNN` references in one text, resolved against the repo's own decision record. A citation
|
|
891
|
+
* the record cannot back is stale in a way age cannot reveal. Qualified refs (another record's)
|
|
892
|
+
* and refs with no ledger to resolve against are counted, never accused.
|
|
893
|
+
*/
|
|
894
|
+
declare function checkDecisionRefs(file: ClaimText, ledger: DecisionLedger, opts: DecisionRefsOptions, counters: ClaimCounters): RefsResult;
|
|
895
|
+
|
|
896
|
+
declare const PREMISE_LENS = "premise";
|
|
897
|
+
declare const PREMISE_BRIEF_FILE: string;
|
|
898
|
+
/** One thing the task named, found or not — the checked half of the brief. */
|
|
899
|
+
type PremiseEntity = ExaminedClaim;
|
|
900
|
+
interface PremiseResult {
|
|
901
|
+
/** The `--json` schema version. */
|
|
902
|
+
schema: "premise/1";
|
|
903
|
+
task: string;
|
|
904
|
+
/** Where the task came from: `argument`, `stdin`, or the file path it was read from. */
|
|
905
|
+
source: string;
|
|
906
|
+
/** The project name from the reckoning. */
|
|
907
|
+
name: string;
|
|
908
|
+
findings: Finding[];
|
|
909
|
+
disclosures: string[];
|
|
910
|
+
/** Everything the task named that etymd could look for — found or not. */
|
|
911
|
+
entities: PremiseEntity[];
|
|
912
|
+
brief: string;
|
|
913
|
+
/** Repo-relative path the brief was written to, or `null` when the repo never opted in. */
|
|
914
|
+
briefPath: string | null;
|
|
915
|
+
}
|
|
916
|
+
interface PremiseOptions {
|
|
917
|
+
root: string;
|
|
918
|
+
task: string;
|
|
919
|
+
source?: string;
|
|
920
|
+
/** Write the brief under `.etymd/` when that directory exists (default true). */
|
|
921
|
+
writeBrief?: boolean;
|
|
922
|
+
}
|
|
923
|
+
/** What the prose promotion declined to read as a claim — counted, then disclosed. */
|
|
924
|
+
interface PromotionSkips {
|
|
925
|
+
/** `pnpm X` / `yarn X` / `bun X` in prose without `run` — a phrase as often as an invocation. */
|
|
926
|
+
bareInvocations: number;
|
|
927
|
+
/** `… run the`, `… run X` — a function word or a one-letter stand-in where a script would be. */
|
|
928
|
+
proseScripts: number;
|
|
929
|
+
/** `github.com/org/repo/…` — a scheme-less URL, not a repo path. */
|
|
930
|
+
hostnameLike: number;
|
|
931
|
+
/** `input/output/` — a slash-joined phrase whose first segment is no directory here. */
|
|
932
|
+
unrootedDirs: number;
|
|
933
|
+
/** `pc:src/x.ts`, `lk: src/x.ts` — a namespace-prefixed mention of ANOTHER repo's tree. */
|
|
934
|
+
namespaced: number;
|
|
935
|
+
}
|
|
936
|
+
interface PromotionContext {
|
|
937
|
+
/** Directory names that exist at the root, in a workspace package, or under their src/ scripts/. */
|
|
938
|
+
rootedDirs: ReadonlySet<string>;
|
|
939
|
+
}
|
|
940
|
+
interface PromotedText {
|
|
941
|
+
text: string;
|
|
942
|
+
skips: PromotionSkips;
|
|
943
|
+
}
|
|
944
|
+
/**
|
|
945
|
+
* People do not backtick paths in a prompt. Promote the bare mentions the claim extractors would
|
|
946
|
+
* otherwise treat as prose — `src/x.ts`, `docs/design/`, `npm run lint` — into code spans, leaving
|
|
947
|
+
* anything already in a code span untouched. Precision over recall: only what an instruction
|
|
948
|
+
* file's extractor would accept is promoted, and every class left as prose is counted.
|
|
949
|
+
*/
|
|
950
|
+
declare function promoteBareTokens(text: string, ctx: PromotionContext): PromotedText;
|
|
951
|
+
declare function runPremise(opts: PremiseOptions): Promise<PremiseResult>;
|
|
952
|
+
/**
|
|
953
|
+
* The half of the premise check only an agent can do, written as a brief it reads before acting.
|
|
954
|
+
* Deterministic: it lists what etymd verified and hands over the three questions reading files
|
|
955
|
+
* cannot answer. It never speculates about what the task "really" means.
|
|
956
|
+
*/
|
|
957
|
+
declare function renderBrief(task: string, findings: Finding[], entities: PremiseEntity[]): string;
|
|
958
|
+
|
|
689
959
|
interface InstructionFile {
|
|
690
960
|
/** Repo-relative path. */
|
|
691
961
|
path: string;
|
|
@@ -719,16 +989,27 @@ interface PathClaims {
|
|
|
719
989
|
paths: string[];
|
|
720
990
|
/** Claims whose every mention sits in create-this prose — skipped, counted, disclosed. */
|
|
721
991
|
prospective: string[];
|
|
992
|
+
/** Claims whose every mention sits behind a namespace prefix (`pc:`) — another repo's tree. */
|
|
993
|
+
namespaced: string[];
|
|
722
994
|
/** Naming stand-ins (`my-custom-skill`) — never real claims. */
|
|
723
995
|
placeholder: string[];
|
|
724
996
|
}
|
|
997
|
+
interface PathClaimOptions {
|
|
998
|
+
/**
|
|
999
|
+
* Read namespace-prefixed mentions (`pc: `src/x.ts``) as another repo's tree — the task
|
|
1000
|
+
* surface, where prompts quote foreign repos behind a legend. Instruction files keep every
|
|
1001
|
+
* backticked span as a claim of this repo.
|
|
1002
|
+
*/
|
|
1003
|
+
namespaces?: boolean;
|
|
1004
|
+
}
|
|
725
1005
|
/**
|
|
726
1006
|
* Repo-relative path claims from single-token inline spans, conservatively filtered. The
|
|
727
1007
|
* load-bearing precision rule (learned from real corpus prose): an extensionless bare token
|
|
728
1008
|
* (`research/trust`, `milestone/mNN`) is prose — a dir claim must end with `/`, a file claim
|
|
729
|
-
* must carry an extension.
|
|
1009
|
+
* must carry an extension. With `namespaces`, a span whose every mention sits behind a
|
|
1010
|
+
* namespace prefix names another repo's tree, not this one.
|
|
730
1011
|
*/
|
|
731
|
-
declare function extractPathClaims(text: string): PathClaims;
|
|
1012
|
+
declare function extractPathClaims(text: string, opts?: PathClaimOptions): PathClaims;
|
|
732
1013
|
|
|
733
1014
|
/** Default total always-loaded words past which the footprint itself becomes a finding. */
|
|
734
1015
|
declare const TOTAL_BUDGET_WORDS: number;
|
|
@@ -825,4 +1106,4 @@ declare const PACK_VERSION = "12";
|
|
|
825
1106
|
declare const VERSION: string;
|
|
826
1107
|
declare const NAME: string;
|
|
827
1108
|
|
|
828
|
-
export { type ApplyResult, type ArtifactFreshness, type AuditOptions, type AuditResult, type Baseline, CONFIG_FILE, type ContextBudget, type ContextBudgets, type ContextFile, DECISIONS_FORMAT_MARKER, DEFAULT_CONFIG, type DetectedArtifact, type DiscoveredCommands, EXTRACTION_THRESHOLD, type EtymdConfig, FLEET_JSON_SCHEMA, FLEET_LENS, type Finding, type FleetContract, type FleetEntry, type FleetManifest, type FleetProfile, type FleetProjectSweep, type FleetSweepOptions, type FleetSweepResult, type FreshnessFacts, type GateInventory, type GateTool, type GeneratedFile, type HookFacts, type InstructionFileSet, type InstructionScope, LENSES, type Ledger, type LedgerDiff, type LedgerEntry, type Lens, type LensReport, type LoadedConfig, type ManifestProblem, NAME, PACK_VERSION, type PackageManager, type PathClaims, type PlanOptions, type ProjectFacts, type StateBudgets, TOTAL_BUDGET_WORDS, VERSION, type WorkflowProfile, type WorkspaceKind, applyFiles, baselineCarriesMachinePath, baselinePath, buildGateInventory, cacheFactsPath, checkManifest, collectWallFindings, configPath, contextEconomyLens,
|
|
1109
|
+
export { type ApplyResult, type ArtifactFreshness, type AuditOptions, type AuditResult, type Baseline, CONFIG_FILE, type ClaimCounters, type ClaimText, type ContextBudget, type ContextBudgets, type ContextFile, DECISIONS_FORMAT_MARKER, DEFAULT_CONFIG, type DecisionLedger, type DecisionRefsOptions, type DetectedArtifact, type DiscoveredCommands, EXTRACTION_THRESHOLD, type EtymdConfig, type ExaminedClaim, FLEET_JSON_SCHEMA, FLEET_LENS, type Finding, type FleetContract, type FleetEntry, type FleetManifest, type FleetProfile, type FleetProjectSweep, type FleetSweepOptions, type FleetSweepResult, type FreshnessFacts, type GateInventory, type GateTool, type GeneratedFile, type HookFacts, type InstructionFileSet, type InstructionScope, LENSES, type Ledger, type LedgerDiff, type LedgerEntry, type Lens, type LensReport, type LoadedConfig, type ManifestProblem, NAME, PACK_VERSION, PREMISE_BRIEF_FILE, PREMISE_LENS, PROPOSAL_SCHEMA, type PackageManager, type PathClaims, type PlanOptions, type PremiseEntity, type PremiseOptions, type PremiseResult, type ProjectFacts, type PromotedText, type PromotionContext, type PromotionSkips, type Proposal, type ProposeResult, RUBRIC_CRITERIA, type RefsResult, type Rubric, type RubricCriterion, type RubricLine, type StateBudgets, TOTAL_BUDGET_WORDS, type TextClaimsOptions, type TextClaimsResult, type TruthEnv, VERSION, type WorkflowProfile, type WorkspaceKind, applyFiles, baselineCarriesMachinePath, baselinePath, buildGateInventory, buildProposals, buildTruthEnv, cacheFactsPath, checkDecisionRefs, checkDocRefs, checkManifest, checkTextClaims, collectWallFindings, configPath, contextEconomyLens, deriveProfile, emptyCounters, expandTilde, extractCommandClaims, extractPathClaims, gateIntegrityLens, guardedPersistenceRoot, instructionTruthLens, isAlwaysAppliedCursorRule, listInstructionFiles, loadDecisionLedger, loadFleetManifest, measureContext, parseRubric, planWorkflow, promoteBareTokens, rankFindings, readBaseline, readCachedFacts, readConfig, readLedger, reconcileLedger, renderBrief, runAudit, runPremise, scanProject, stateFreshnessLens, sweepFleet, withoutMachinePath, writeBaseline, writeCachedFacts, writeLedger };
|