tickmarkr 2.6.4 → 2.6.6
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/README.md +7 -3
- package/dist/adapters/catalog-remote.d.ts +23 -0
- package/dist/adapters/catalog-remote.js +38 -0
- package/dist/adapters/claude-code.d.ts +1 -1
- package/dist/adapters/claude-code.js +4 -1
- package/dist/adapters/codex-commit-check.d.ts +36 -0
- package/dist/adapters/codex-commit-check.js +205 -0
- package/dist/adapters/codex.d.ts +1 -0
- package/dist/adapters/codex.js +12 -6
- package/dist/adapters/model-discovery-check.d.ts +33 -0
- package/dist/adapters/model-discovery-check.js +123 -0
- package/dist/adapters/model-lints.d.ts +1 -1
- package/dist/adapters/model-lints.js +4 -0
- package/dist/adapters/prompt.js +3 -2
- package/dist/adapters/types.d.ts +10 -0
- package/dist/cli/commands/approve.js +10 -4
- package/dist/cli/commands/doctor.d.ts +2 -0
- package/dist/cli/commands/doctor.js +17 -3
- package/dist/cli/commands/fleet.d.ts +10 -1
- package/dist/cli/commands/fleet.js +363 -106
- package/dist/cli/commands/init.js +10 -3
- package/dist/cli/commands/plan.js +76 -4
- package/dist/cli/commands/verify.d.ts +1 -1
- package/dist/cli/commands/verify.js +65 -15
- package/dist/config/fleet-overlay.d.ts +16 -1
- package/dist/config/fleet-overlay.js +230 -28
- package/dist/drivers/orca.d.ts +34 -2
- package/dist/drivers/orca.js +206 -32
- package/dist/gates/cache.d.ts +4 -0
- package/dist/gates/cache.js +10 -2
- package/dist/gates/llm.d.ts +4 -1
- package/dist/gates/llm.js +6 -1
- package/dist/gates/review.js +8 -3
- package/dist/gates/run-gates.d.ts +5 -3
- package/dist/gates/run-gates.js +112 -56
- package/dist/gates/test-manifest.d.ts +3 -0
- package/dist/gates/test-manifest.js +1 -1
- package/dist/gates/timeout-shaped.d.ts +3 -0
- package/dist/gates/timeout-shaped.js +10 -0
- package/dist/run/daemon.js +326 -130
- package/dist/run/git.js +9 -0
- package/dist/run/journal.d.ts +6 -2
- package/dist/run/journal.js +22 -7
- package/dist/run/launchservices-check.d.ts +56 -0
- package/dist/run/launchservices-check.js +117 -0
- package/dist/run/operator-state.d.ts +22 -2
- package/dist/run/operator-state.js +20 -3
- package/dist/run/title-environment.d.ts +45 -0
- package/dist/run/title-environment.js +127 -0
- package/dist/run/title-preload.cjs +38 -0
- package/dist/run/title-preload.d.cts +1 -0
- package/dist/tui/cockpit/board.js +12 -6
- package/dist/tui/cockpit/keys.d.ts +8 -0
- package/dist/tui/cockpit/keys.js +4 -1
- package/dist/tui/cockpit/layout.d.ts +2 -2
- package/dist/tui/cockpit/layout.js +2 -2
- package/dist/tui/cockpit/live-runtime.js +46 -20
- package/dist/tui/cockpit/live-store.d.ts +24 -1
- package/dist/tui/cockpit/live-store.js +99 -8
- package/dist/tui/cockpit/log-view.d.ts +28 -0
- package/dist/tui/cockpit/log-view.js +60 -0
- package/dist/tui/cockpit/run-view.js +4 -0
- package/dist/tui/cockpit/shell.d.ts +2 -1
- package/dist/tui/cockpit/shell.js +6 -4
- package/dist/tui/ink/fleet-app.d.ts +37 -10
- package/dist/tui/ink/fleet-app.js +65 -21
- package/package.json +1 -1
- package/skills/tickmarkr-auto/SKILL.md +32 -2
- package/skills/tickmarkr-loop/SKILL.md +46 -2
- package/skills/tickmarkr-overseer/SKILL.md +83 -8
- package/skills/tickmarkr-overseer/scripts/classify-vitest-log.sh +58 -16
- package/skills/tickmarkr-overseer/scripts/grade-ci.sh +19 -6
- package/skills/tickmarkr-overseer/scripts/watch-parks.sh +121 -64
package/dist/adapters/types.d.ts
CHANGED
|
@@ -51,7 +51,17 @@ export interface AuthHealth {
|
|
|
51
51
|
modelAuth?: Record<string, ModelAuth>;
|
|
52
52
|
modelIdentities?: Record<string, string>;
|
|
53
53
|
modelRetirements?: Record<string, ModelRetirement | null>;
|
|
54
|
+
codexCommit?: CodexCommitStatus;
|
|
55
|
+
launchServices?: LaunchServicesRecord;
|
|
54
56
|
}
|
|
57
|
+
export interface LaunchServicesRecord {
|
|
58
|
+
pid: number;
|
|
59
|
+
start: string;
|
|
60
|
+
advisory?: string;
|
|
61
|
+
}
|
|
62
|
+
/** allowed: linked branch commit landed, shared hooks/common root denied · protected: commit denied, controls
|
|
63
|
+
* readable · escape: a unique hostile member was written · unknown: unreadable or contradictory receipts. */
|
|
64
|
+
export type CodexCommitStatus = "allowed" | "protected" | "escape" | "unknown";
|
|
55
65
|
export declare function modelAuthed(health: AuthHealth | undefined, model: string, allowUnverifiedModels?: boolean): boolean;
|
|
56
66
|
export interface Invocation {
|
|
57
67
|
command: string;
|
|
@@ -210,11 +210,17 @@ export async function approve(argv, cwd = process.cwd()) {
|
|
|
210
210
|
if (namedGate !== undefined && namedGate !== park?.failedGate) {
|
|
211
211
|
throw new Error(`refusing mismatched gate for ${taskId}: --gate ${namedGate} but park ${bindingToken(parkBinding)} failed ${park?.failedGate ?? "no gate"} — nothing appended`);
|
|
212
212
|
}
|
|
213
|
-
|
|
213
|
+
// A scope-request park is released one of two ways: --files widens files[], or a nonempty --reason
|
|
214
|
+
// refuses the expansion and funds a plain worker within the current files[] — the reason rides into
|
|
215
|
+
// the next brief as a standing ruling (journaledFailureBrief). No reason, no release: the refusal is
|
|
216
|
+
// a ruling only when it says why. The cockpit menu still offers neither (it has no reason entry).
|
|
217
|
+
const scopeRefusal = park?.kind === "scope-request" && !decisions && files === undefined && Boolean(reason?.trim());
|
|
218
|
+
if ((park?.kind === "scope-request" && !decisions && !scopeRefusal) || files !== undefined) {
|
|
214
219
|
if (park?.kind !== "scope-request")
|
|
215
220
|
throw new Error("--files requires a scope-request park");
|
|
216
|
-
if (!files?.length)
|
|
217
|
-
throw new Error(`scope-request for ${taskId} requires --files <glob
|
|
221
|
+
if (!files?.length) {
|
|
222
|
+
throw new Error(`scope-request for ${taskId} requires --files <glob,…> to widen files[], or \`tickmarkr approve ${runId} ${taskId} --reason <text>\` to refuse the expansion and continue within the current files[]`);
|
|
223
|
+
}
|
|
218
224
|
if (decisions)
|
|
219
225
|
throw new Error("--files cannot be combined with --waive, --uphold or --recheck");
|
|
220
226
|
const graph = applyScopeAmendments(loadGraph(cwd), journal, false, engagementReleased(events));
|
|
@@ -358,7 +364,7 @@ export async function approve(argv, cwd = process.cwd()) {
|
|
|
358
364
|
park: parkBinding,
|
|
359
365
|
});
|
|
360
366
|
const token = capPark ? "fresh-budget" : "dispatch";
|
|
361
|
-
return disposition(cwd, runId, token, `approved ${taskId} in ${runId} — by ${by}`, serialization.contended);
|
|
367
|
+
return disposition(cwd, runId, token, `approved ${taskId} in ${runId} — by ${by}${scopeRefusal ? "; scope expansion refused, files[] unchanged" : ""}`, serialization.contended);
|
|
362
368
|
}
|
|
363
369
|
finally {
|
|
364
370
|
serialization.release();
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type ClaudeAlias } from "../../adapters/claude-code.js";
|
|
2
2
|
import type { WorkerAdapter } from "../../adapters/types.js";
|
|
3
3
|
import { type KimiDoctorTurnResult } from "../../adapters/kimi.js";
|
|
4
|
+
import { type CodexSandbox } from "../../adapters/codex-commit-check.js";
|
|
4
5
|
import { type CatalogFetcher, type CatalogReadResult } from "../../adapters/catalog-remote.js";
|
|
5
6
|
import { type ShResult } from "../../run/git.js";
|
|
6
7
|
import { type VitestListResult } from "../../gates/acceptance.js";
|
|
@@ -17,6 +18,7 @@ export declare function recentReviewDemotions(cwd: string, lastRuns?: number): R
|
|
|
17
18
|
export type DoctorOpts = {
|
|
18
19
|
banner?: boolean;
|
|
19
20
|
kimiTurnProbe?: (cwd: string) => Promise<KimiDoctorTurnResult>;
|
|
21
|
+
codexSandbox?: CodexSandbox;
|
|
20
22
|
resolveClaudeAliasIdentity?: (cwd: string, alias: ClaudeAlias) => string | undefined;
|
|
21
23
|
catalog?: CatalogReadResult;
|
|
22
24
|
catalogNow?: () => Date;
|
|
@@ -14,11 +14,15 @@ import { loadConfig, overlayPreferShapes } from "../../config/config.js";
|
|
|
14
14
|
import { HerdrDriver } from "../../drivers/herdr.js";
|
|
15
15
|
import { ORCA_FIXTURE_VERSION, parseEnvelope, resolveOrcaCliBinary } from "../../drivers/orca.js";
|
|
16
16
|
import { kimi, probeKimiDoctorTurn } from "../../adapters/kimi.js";
|
|
17
|
+
import { recordCodexCommit } from "../../adapters/codex-commit-check.js";
|
|
18
|
+
import { codex } from "../../adapters/codex.js";
|
|
17
19
|
import { denyPreferCollisionLine, denyPreferCollisions, disallowedBy, excludedChannels, exclusionLine, observedSeat, preferRanks } from "../../route/preference.js";
|
|
18
20
|
import { CATALOG_REFRESH_TIMEOUT_MS, LIVEBENCH_TABLE_DATE, formatCatalogRefreshLegs, readCachedCatalog, refreshCatalogCommand } from "../../adapters/catalog-remote.js";
|
|
19
21
|
import { sh } from "../../run/git.js";
|
|
20
22
|
import { auditNamedTestOracles, listVitestTests } from "../../gates/acceptance.js";
|
|
21
23
|
import { readReviewNoVerdictHistory, reviewNoVerdictRows } from "../../run/journal.js";
|
|
24
|
+
import { checkModelDiscovery } from "../../adapters/model-discovery-check.js";
|
|
25
|
+
import { recordLaunchServices } from "../../run/launchservices-check.js";
|
|
22
26
|
/** Where a newer `table_<date>.csv` is discovered — the deployed site builds filenames by
|
|
23
27
|
* concatenation and publishes no index, so the release listing is the only enumerable surface. */
|
|
24
28
|
export const LIVEBENCH_RELEASES_URL = "https://api.github.com/repos/LiveBench/livebench.github.io/contents/public";
|
|
@@ -578,6 +582,7 @@ export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(
|
|
|
578
582
|
};
|
|
579
583
|
}
|
|
580
584
|
}
|
|
585
|
+
await recordCodexCommit(adapters, health, cwd, opts.codexSandbox);
|
|
581
586
|
// MODEL-02: detect models where the adapter exposes a list surface, BEFORE writing doctor.json (write once, below).
|
|
582
587
|
// Fail OPEN — the inverse of gates' fail-closed: detection is advisory, so a broken list surface NEVER fails doctor.
|
|
583
588
|
for (const a of adapters) {
|
|
@@ -659,12 +664,17 @@ export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(
|
|
|
659
664
|
}
|
|
660
665
|
}
|
|
661
666
|
}
|
|
662
|
-
|
|
667
|
+
const discovery = await checkModelDiscovery({ cwd, cfg, adapters, health, catalog, resolved: resolvedIdentitySnapshot, mayRefresh: !opts.catalog && !catalogRefreshLine && catalogRefreshAllowed, fetcher: opts.catalogFetcher, now: opts.catalogNow });
|
|
668
|
+
catalog = discovery.catalog;
|
|
669
|
+
aliasDriftFindings.push(...discovery.findings);
|
|
670
|
+
const launchServices = await recordLaunchServices(readDoctor(cwd), health);
|
|
671
|
+
writeDoctor(cwd, launchServices.health);
|
|
663
672
|
const rows = adapters.map((a) => {
|
|
664
673
|
const h = health[a.id];
|
|
665
674
|
// OBS-503: a crash-on-version verdict carries its reason in note — print it instead of the lie.
|
|
666
675
|
const state = !h.installed ? (h.note ?? "not installed") : `${h.version ?? "installed"}${h.note ? ` (${h.note})` : ""}`;
|
|
667
|
-
|
|
676
|
+
// v2.6.6 T9 (K): a Codex sandbox escape is a BLOCKING security warning — never a passing row
|
|
677
|
+
const healthy = h.installed && (a.id !== kimi.id || h.authed) && !(a.id === codex.id && h.codexCommit === "escape");
|
|
668
678
|
return alignedStatusRow(healthy ? "pass" : "fail", a.id, state);
|
|
669
679
|
});
|
|
670
680
|
const reviewDemotions = recentReviewDemotions(cwd);
|
|
@@ -807,6 +817,8 @@ export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(
|
|
|
807
817
|
lintRows.push(...flagDriftWarnings(adapters, health).map(attentionRow));
|
|
808
818
|
// OBS-145: resolved-identity drift is advisory display warning.
|
|
809
819
|
lintRows.push(...aliasDriftFindings.map(attentionRow));
|
|
820
|
+
if (launchServices.line)
|
|
821
|
+
lintRows.push(attentionRow(launchServices.line));
|
|
810
822
|
const resolvedCatalogModel = (adapter, model) => {
|
|
811
823
|
if (adapter !== "claude-code" || !(model in CLAUDE_ALIAS_IDENTITY_STAMPS))
|
|
812
824
|
return undefined;
|
|
@@ -895,9 +907,11 @@ export async function doctor(_argv, cwd = process.cwd(), adapters = allAdapters(
|
|
|
895
907
|
rows.push(` ${dim(`catalog · ${advisory.display}`)}`);
|
|
896
908
|
if (!listAllModels && bulk.length) {
|
|
897
909
|
const uncovered = bulk.filter((adv) => adv.coverage === "uncovered").length;
|
|
898
|
-
const
|
|
910
|
+
const unknown = bulk.filter((adv) => adv.coverage === "unknown").length;
|
|
911
|
+
const evidenceOnly = bulk.length - uncovered - unknown;
|
|
899
912
|
const parts = [
|
|
900
913
|
...(uncovered ? [`${uncovered} uncovered by ${catalog.source === "cache" ? "cached catalogs" : "vendored catalog"}`] : []),
|
|
914
|
+
...(unknown ? [`${unknown} coverage unknown after a failed refresh`] : []),
|
|
901
915
|
...(evidenceOnly ? [`${evidenceOnly} covered without a tier suggestion`] : []),
|
|
902
916
|
];
|
|
903
917
|
rows.push(` ${dim(`catalog · ${parts.join(" · ")} — tickmarkr doctor --models lists each`)}`);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type CatalogFetcher, type CatalogReadResult } from "../../adapters/catalog-remote.js";
|
|
2
2
|
import type { WorkerAdapter } from "../../adapters/types.js";
|
|
3
|
-
import type
|
|
3
|
+
import { type MapEntry, type ModeResolution, type RoutingMode, type TickmarkrConfig } from "../../config/config.js";
|
|
4
|
+
import type { FleetEditorResult, FleetStagedDeny, FleetStagedMetadata } from "../../tui/ink/fleet-app.js";
|
|
4
5
|
type FleetEditorProps = Parameters<typeof import("../../tui/ink/fleet-app.js").runFleetInkEditor>[0];
|
|
5
6
|
export type FleetInput = NodeJS.ReadableStream & {
|
|
6
7
|
isTTY?: boolean;
|
|
@@ -44,6 +45,14 @@ export declare function assembleFleetEditor(cwd: string, adapters: WorkerAdapter
|
|
|
44
45
|
props: FleetEditorProps;
|
|
45
46
|
commit: (result: FleetEditorResult) => string;
|
|
46
47
|
renderWhy: () => string;
|
|
48
|
+
previewConfig: (mode: RoutingMode, map: Record<string, MapEntry>, deny: FleetStagedDeny, stage?: FleetStagedMetadata) => {
|
|
49
|
+
ok: true;
|
|
50
|
+
cfg: TickmarkrConfig;
|
|
51
|
+
mode: ModeResolution;
|
|
52
|
+
} | {
|
|
53
|
+
ok: false;
|
|
54
|
+
error: string;
|
|
55
|
+
};
|
|
47
56
|
} | {
|
|
48
57
|
unavailable: string;
|
|
49
58
|
}>;
|