Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
8ec0f1a
fix(scan): report parent progress from persisted tool output
mldangelo-oai Oct 11, 2026
a3d8b2f
fix(scan): synchronize parent progress across live and saved events
mldangelo-oai Oct 11, 2026
99bef63
fix(scan): reconcile repeated progress and truncated inventories
mldangelo-oai Oct 11, 2026
0e0bfe5
fix(sdk): reconcile parent progress with native completion order
mldangelo-oai Oct 11, 2026
69a51e7
fix(sdk): separate progress source ordering from display updates
mldangelo-oai Oct 11, 2026
a6a262e
fix(sdk): retain compact progress ordering metadata
mldangelo-oai Oct 11, 2026
d820479
fix(sdk): preserve receipts across progress reconciliation
mldangelo-oai Oct 11, 2026
c99bfd3
test(sdk): synchronize worker progress observations
mldangelo-oai Oct 11, 2026
6d5e225
fix(sdk): reconcile accepted inventory and resumed receipts
mldangelo-oai Oct 11, 2026
ef72f55
fix(sdk): preserve progress across batched inventory updates
mldangelo-oai Oct 11, 2026
f029277
test: expose isolated subprocess progress
mldangelo-oai Oct 11, 2026
a6ff060
test: identify active API test cases in CI
mldangelo-oai Oct 11, 2026
59d5e75
test(sdk): keep synthetic progress polling alive
mldangelo-oai Oct 11, 2026
94f3bbf
fix(scan): preserve recovered inventory and multipart progress
mldangelo-oai Oct 11, 2026
c7772c2
fix(scan): retain progress pending native inventory proof
mldangelo-oai Oct 11, 2026
7ab5877
fix(scan): retain deferred parent receipt order
mldangelo-oai Oct 11, 2026
6e3275c
fix(scan): retain progress across asynchronous receipt boundaries
mldangelo-oai Oct 11, 2026
a313aa6
fix(scan): preserve parent phase provenance during recovery
mldangelo-oai Oct 11, 2026
9ca3a56
fix(scan): recover complete progress prefixes from saved output
mldangelo-oai Oct 11, 2026
76eff38
fix(sdk): retain admitted parent progress facts
mldangelo-oai Oct 11, 2026
334393c
test(sdk): keep new polling fixtures alive
mldangelo-oai Oct 11, 2026
752adce
fix(sdk): reject superseded saved inventories
mldangelo-oai Oct 11, 2026
6b3cc5f
fix(sdk): retain eligible live progress receipts
mldangelo-oai Oct 11, 2026
4d83f80
fix(sdk): correlate progress across dropped events
mldangelo-oai Oct 11, 2026
33d1cdc
test(sdk): stabilize progress observer fixtures
mldangelo-oai Oct 11, 2026
27050d7
fix(sdk): retain parent facts across inventory recovery
mldangelo-oai Oct 11, 2026
ed9ebed
fix: preserve parent scan phase at equal worker coverage
mldangelo-oai Oct 11, 2026
2408aad
fix(sdk): preserve distinct worker progress receipts
mldangelo-oai Oct 11, 2026
8b542cd
Merge commit '825e7fd059a8047eef6fac6c814dce294d58fc18' into mdangelo…
mldangelo-oai Oct 11, 2026
f9e17f3
refactor(scan): derive parent marker bookkeeping from existing state
mldangelo-oai Oct 11, 2026
2a13bd3
fix(scan): deduplicate message completion projections without progress
mldangelo-oai Oct 11, 2026
5d55957
Merge commit '825e7fd059a8047eef6fac6c814dce294d58fc18' into mdangelo…
mldangelo-oai Oct 11, 2026
4823334
refactor(scan): simplify progress state and fixtures
mldangelo-oai Oct 11, 2026
a1215d4
Merge commit '2a13bd35c51632bb972e0e18cc4f3d11f1616b1a' into mdangelo…
mldangelo-oai Oct 11, 2026
75879c7
fix(scan): preserve progress ordering and validation ownership
mldangelo-oai Oct 11, 2026
41a192f
Merge commit '5efc3d9416132c835aba4225a42903c1a7dedf61' into mdangelo…
mldangelo-oai Oct 11, 2026
0f31372
test: trigger reads explicitly in progress race fixtures
mldangelo-oai Oct 11, 2026
2153854
chore: merge main and reconcile progress imports
mldangelo-oai Oct 11, 2026
bfc34ca
Merge commit '215385419c8738077dda8b5754fe053176583534' into mdangelo…
mldangelo-oai Oct 11, 2026
c461c1e
fix: restore current progress after unmatched legacy completions
mldangelo-oai Oct 11, 2026
d4a2ab4
test: trigger session reads before progress close gates
mldangelo-oai Oct 11, 2026
5631551
fix: preserve proven inventory across omitted live notifications
mldangelo-oai Oct 11, 2026
e5e9c23
fix: reconcile saved-only progress through admitted source facts
mldangelo-oai Oct 11, 2026
7b9084e
Merge external progress test barrier fixes
mldangelo-oai Oct 11, 2026
c7142b1
fix(scan): admit inventory scope and phase by source order
mldangelo-oai Oct 11, 2026
ae38df7
test: keep custom validation polling fixtures active
mldangelo-oai Oct 11, 2026
6ea0bb1
fix(scan): defer repeated inventories until review order is known
mldangelo-oai Oct 11, 2026
33240ba
fix(scan): preserve progress across command display projections
mldangelo-oai Oct 11, 2026
a04dc03
fix(scan): retain live progress across lossy command snapshots
mldangelo-oai Oct 12, 2026
49b5b0d
test(scan): arm snapshot gate before the first poll
mldangelo-oai Oct 12, 2026
f17b5d0
fix(scan): reconsider inventory when review order becomes known
mldangelo-oai Oct 12, 2026
364e709
fix(scan): preserve inventory provenance across command projections
mldangelo-oai Oct 12, 2026
9674cc1
fix(scan): retain authoritative inventory through session replay
mldangelo-oai Oct 12, 2026
5b3949f
fix(scan): preserve inventory ownership during progress replay
mldangelo-oai Oct 12, 2026
9afd063
test(scan): synchronize worker progress after live inventory
mldangelo-oai Oct 12, 2026
1416455
fix(scan): retain source authority across progress copies
mldangelo-oai Oct 12, 2026
c38b37b
fix(sdk): preserve source order when replaying inventory
mldangelo-oai Oct 12, 2026
700895a
fix(sdk): bind inventory replay to accepted source markers
mldangelo-oai Oct 12, 2026
c7f37b3
fix(sdk): preserve inventory occurrence ordering during replay
mldangelo-oai Oct 12, 2026
a5153a0
fix(sdk): retain progress evidence across polling
mldangelo-oai Oct 12, 2026
dc84ba5
fix(sdk): preserve progress occurrence authority
mldangelo-oai Oct 12, 2026
09c254b
fix(sdk): carry source bounds through progress reconciliation
mldangelo-oai Oct 12, 2026
0645377
fix(sdk): retain unresolved progress evidence
mldangelo-oai Oct 12, 2026
4c37bdb
fix(sdk): preserve command proof across progress markers
mldangelo-oai Oct 12, 2026
5944354
fix(sdk): separate source proof from progress admission
mldangelo-oai Oct 12, 2026
d2aa108
fix(sdk): evaluate progress against source-ordered inventory
mldangelo-oai Oct 12, 2026
c61964c
fix(sdk): preserve inventory authority as source evidence resolves
mldangelo-oai Oct 13, 2026
99d675e
fix(sdk): reconcile source proof before progress admission
mldangelo-oai Oct 13, 2026
2ce1b43
fix(sdk): keep inventory cutoffs tied to source evidence
mldangelo-oai Oct 13, 2026
58bf335
fix(sdk): revalidate inventory evidence across polls
mldangelo-oai Oct 13, 2026
299334d
fix(sdk): preserve bounded inventory marker order
mldangelo-oai Oct 13, 2026
cd25b71
fix(sdk): reconcile bounded inventory intervals together
mldangelo-oai Oct 13, 2026
3f15a44
fix(sdk): select eligible inventory before scope projection
mldangelo-oai Oct 13, 2026
8ef64c9
fix(sdk): preserve review eligibility and bounded projection order
mldangelo-oai Oct 13, 2026
cde0168
fix(sdk): retain inventory proof through source requalification
mldangelo-oai Oct 13, 2026
44d781b
fix(sdk): preserve admitted inventory and prefix ordering
mldangelo-oai Oct 13, 2026
2bdff2f
chore: merge main and retain progress and usage accounting
codex Oct 13, 2026
f638eec
fix(sdk): corroborate retained inventory after truncated copies
mldangelo-oai Oct 13, 2026
c833e92
fix(sdk): preserve recovered scope and progress order
mldangelo-oai Oct 13, 2026
b3c3473
fix(sdk): requalify the displayed progress receipt
mldangelo-oai Oct 13, 2026
2614ac0
merge: integrate main into parent progress reconciliation
mldangelo-oai Oct 17, 2026
2e2c776
test(progress): share the bundle for memory regressions
mldangelo-oai Oct 17, 2026
2504c4a
Merge main and compose parent progress tracking
mldangelo-oai Oct 20, 2026
e30c831
Merge latest main and retain parent phase during inventory recovery
mldangelo-oai Oct 20, 2026
b5991e7
Merge commit '004b9092b7356f4e6c9572844ee6074f9ddd8e1d' into mdangelo…
mldangelo-oai Oct 20, 2026
36729a0
test(progress): preserve parent phase in replay fixtures
mldangelo-oai Oct 20, 2026
963a775
Merge main and retain parent progress fixtures
mldangelo-oai Oct 20, 2026
3e60d92
Merge remote-tracking branch 'origin/main' into mdangelo/codex/repair…
mldangelo-oai Oct 22, 2026
3a54226
fix(progress): preserve incomplete saved message sequences
mldangelo-oai Oct 22, 2026
c610f53
Merge main into PR branch
mldangelo-oai Oct 22, 2026
6ab0898
Merge main into PR branch
mldangelo-oai Oct 23, 2026
4d81cff
Merge latest main into PR branch
mldangelo-oai Oct 23, 2026
db3b1d7
Merge latest main smoke timeout fixes into PR branch
mldangelo-oai Oct 23, 2026
8c3f5e5
chore: merge main container security update
mldangelo-oai Oct 23, 2026
1fcd8cb
Merge main and preserve parent progress during usage replay
mldangelo-oai Oct 25, 2026
d29c1d7
fix(progress): include final worker usage during event replay
mldangelo-oai Oct 25, 2026
e706678
refactor(progress): share inventory and replay fixtures with current …
mldangelo-oai Oct 28, 2026
9192a9f
Merge current main into scan-parent-progress
mldangelo-oai Oct 28, 2026
fdf6217
refactor(progress): share ordered marker projection and frontier updates
mldangelo-oai Oct 28, 2026
37e5405
test(progress): reuse the replay fixture for source-order cases
mldangelo-oai Oct 28, 2026
daec987
chore: merge main into parent progress reconciliation
mldangelo-oai Oct 30, 2026
0c1cd60
Merge branch 'main' into mdangelo/codex/scan-parent-progress
mldangelo-oai Nov 3, 2026
d49574c
Merge main into scan progress
mldangelo-oai Nov 3, 2026
a52f005
test(sdk): isolate the policy preview fixture build
mldangelo-oai Nov 3, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
114 changes: 80 additions & 34 deletions sdk/typescript/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ import {
estimateScanCost,
ScanCostTracker,
type ScanCost,
type ParentProgressSource,
type ScanSessionEvent,
type ScanUsageObservation,
type ScanWorkerEvent,
Expand Down Expand Up @@ -1979,7 +1980,9 @@ export class CodexSecurity {
let scanProgressTracker: ScanProgressTracker | null = null;
let savedProviderProfile: ProviderProfile | undefined;
let artifactRestorationFailure: OutputDirectoryError | null = null;
let customValidationComplete = false;
const customValidation = {
status: "pending" as "pending" | "running" | "complete",
};
let completionCost: ScanCost | null = null;
let scanTurnStatus: "in_progress" | "completed" | "failed" | null = null;
let budgetRecovery: {
Expand Down Expand Up @@ -2317,31 +2320,63 @@ export class CodexSecurity {
let reviewedFileCount = 0;
let latestPhase: ScanProgress["phase"] = "preflight";
let reviewItems: ScanProgress["reviewItems"];
const reportProgress = (progress: ScanProgress): void => {
let lastProgress: string | null = null;
const progressKey = (progress: ScanProgress): string =>
`${progress.phase}:${progress.filesCompleted}:${progress.filesTotal}:${progress.reviewItems?.completed}:${progress.reviewItems?.total}`;
const reportProgress = (
progress: ScanProgress,
source?: ParentProgressSource,
): void => {
const liveEvent =
source?.reconciled === true ? undefined : source?.event;
if (
scopeFileCount === null ||
progress.filesTotal > scopeFileCount ||
progress.filesCompleted < reviewedFileCount
liveEvent !== undefined &&
!tracker.recordParentProgress(progress, liveEvent)
)
return;
const inventory =
source?.inventory === true ||
(progress.phase === "discovery" &&
reviewedFileCount === 0 &&
progress.filesCompleted === 0);
Comment thread
mldangelo-oai marked this conversation as resolved.
Resolved
const filesTotal = inventory ? progress.filesTotal : scopeFileCount;
if (
filesTotal === null ||
progress.filesTotal > filesTotal ||
(source?.inventory !== true &&
progress.filesCompleted < reviewedFileCount)
) {
if (liveEvent !== undefined) tracker.deferParentInventory(liveEvent);
return;
}
if (inventory) {
scopeFileCount = filesTotal;
tracker.setExpectedFilesTotal(filesTotal);
}
reviewedFileCount = progress.filesCompleted;
if (liveEvent !== undefined)
tracker.acceptParentProgress(progress, liveEvent);
if (
source !== undefined ||
mode === "deep" ||
scanPhaseSchema.options.indexOf(progress.phase) >
scanPhaseSchema.options.indexOf(latestPhase)
) {
latestPhase = progress.phase;
}
notifyObserver(
options,
"onProgress",
)({
const update = {
...progress,
phase: latestPhase,
filesTotal: scopeFileCount,
phase:
customValidation.status === "running"
? ("validation" as const)
: latestPhase,
filesTotal,
...(reviewItems === undefined ? {} : { reviewItems }),
});
};
const key = progressKey(update);
if (lastProgress === key) return;
lastProgress = key;
notifyObserver(options, "onProgress")(update);
};
const reportWorkerStatus = (status: ScanWorkerStatus): void => {
if (mode !== "deep") {
Expand Down Expand Up @@ -2408,12 +2443,20 @@ export class CodexSecurity {
onProgress:
options.onProgress === undefined
? undefined
: (progress) =>
reportProgress({
...progress,
// Worker counts belong to the parent scan's current phase.
phase: mode === "deep" ? progress.phase : latestPhase,
}),
: (progress, source) =>
reportProgress(
{
...progress,
// Only worker counts use the last accepted parent phase.
phase:
mode === "deep" ||
(source !== undefined &&
(source.reconciled !== true || !source.worker))
? progress.phase
: latestPhase,
},
source,
),
onCost:
options.onCost === undefined && options.maxCostUsd === undefined
? undefined
Expand Down Expand Up @@ -3038,6 +3081,7 @@ export class CodexSecurity {
),
)}`;
}
tracker.beginParentTurn(resumeThreadId !== undefined);
const events = directDeepScan
? (this.#dependencies.runDeepScan ?? runDeepScan)({
codexOptions,
Expand Down Expand Up @@ -3125,6 +3169,7 @@ export class CodexSecurity {
// This turn follows the primary scan's reporting phase.
scanProgressTracker?.stop();
latestPhase = "validation";
customValidation.status = "running";
if (scopeFileCount !== null)
reportProgress({
phase: "validation",
Expand Down Expand Up @@ -3164,7 +3209,7 @@ export class CodexSecurity {
return turn.finalResponse;
},
});
customValidationComplete = true;
customValidation.status = "complete";
}
budgetAbortController.abort();
const snapshot = await tracker.stop(usage).catch((error: unknown) => {
Expand Down Expand Up @@ -3221,18 +3266,11 @@ export class CodexSecurity {
onTrustedAccessStatus: options.onTrustedAccessStatus,
onReconnect: options.onReconnect,
onActivity: options.onActivity,
onProgress: (progress) => {
if (
progress.phase === "discovery" &&
progress.filesCompleted === 0 &&
reviewedFileCount === 0 &&
progress.filesTotal !== scopeFileCount
) {
scopeFileCount = progress.filesTotal;
tracker.setExpectedFilesTotal(scopeFileCount);
}
reportProgress(progress);
},
onProgressItem:
options.onProgress === undefined
? undefined
: (event) => tracker.recordParentItem(event),
onProgress: reportProgress,
onWorkerStatus: reportWorkerStatus,
onWarning: options.onWarning,
onObserverError: options.onObserverError,
Expand Down Expand Up @@ -3599,7 +3637,7 @@ export class CodexSecurity {
if (activeScan !== null && options.resumeScanId === undefined) {
if (
options.validationPrompt !== undefined &&
!customValidationComplete
customValidation.status !== "complete"
) {
await writeCustomValidationStatus(scanDir, {
scanId: activeScan.id,
Expand Down Expand Up @@ -5068,7 +5106,8 @@ interface ScanEventRunOptions extends Pick<ScanOptions, "onReconnect"> {
onScanStarted?: () => void;
onTrustedAccessStatus?: (status: ScanTrustedAccessStatus) => void;
onActivity?: (activity: ScanActivity) => void;
onProgress?: (progress: ScanProgress) => void;
onProgressItem?: (event: Readonly<Record<string, unknown>>) => void;
onProgress?: (progress: ScanProgress, source: ParentProgressSource) => void;
onWorkerStatus?: (status: ScanWorkerStatus) => void;
onWarning?: (warning: string) => void;
onObserverError?: (observer: ScanObserverName, error: unknown) => void;
Expand Down Expand Up @@ -5112,8 +5151,15 @@ export async function runScanEvents(
)) {
notifyObserver(options, "onActivity")(activity);
}
options.onProgressItem?.(event);
for (const progress of scanProgressUpdatesFromEvent(event)) {
notifyObserver(options, "onProgress")(progress);
notifyObserver(
{
onProgress: (update) => options.onProgress?.(update, { event }),
onObserverError: options.onObserverError,
},
"onProgress",
)(progress);
}
const workerStatus = workerStatusFromEvent(event);
if (workerStatus !== null) {
Expand Down
Loading
Loading