@open-agent-toolkit/cli 0.2.50 → 0.2.52
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/assets/bundle-metadata.json +1 -1
- package/assets/docs/cli-utilities/bootstrap.md +6 -2
- package/assets/docs/cli-utilities/tool-packs.md +87 -33
- package/assets/docs/provider-sync/commands.md +30 -2
- package/assets/docs/provider-sync/config.md +19 -0
- package/assets/docs/provider-sync/manifest-and-drift.md +37 -0
- package/assets/docs/provider-sync/providers.md +69 -2
- package/assets/docs/provider-sync/scope-and-surface.md +44 -0
- package/assets/docs/reference/cli-reference.md +21 -5
- package/assets/docs/reference/file-locations.md +8 -2
- package/assets/docs/reference/oat-directory-structure.md +25 -9
- package/assets/docs/workflows/projects/artifacts.md +9 -4
- package/assets/docs/workflows/projects/evidence-layers.md +110 -1
- package/assets/docs/workflows/projects/implementation-execution.md +13 -0
- package/assets/docs/workflows/projects/lifecycle.md +17 -5
- package/assets/docs/workflows/projects/orchestration-model.md +18 -0
- package/assets/docs/workflows/projects/picking-up-projects.md +26 -9
- package/assets/docs/workflows/projects/pr-flow.md +5 -3
- package/assets/docs/workflows/projects/reviewing-oat-prs.md +12 -8
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-dispatch-subagents/SKILL.md +57 -1
- package/assets/skills/oat-dispatch-subagents/references/record-schema.md +77 -1
- package/assets/skills/oat-project-autonomous/references/gate-inventory.md +3 -3
- package/assets/skills/oat-project-complete/SKILL.md +193 -26
- package/assets/skills/oat-project-complete/scripts/execute-synced-archive-entry.mjs +306 -0
- package/assets/skills/oat-project-complete/scripts/finalize-synced-archive.mjs +125 -0
- package/assets/skills/oat-project-complete/scripts/parse-synced-archive-resume-fields.mjs +106 -0
- package/assets/skills/oat-project-complete/scripts/recover-completion-receipts.mjs +110 -0
- package/assets/skills/oat-project-complete/scripts/resolve-synced-archive-entry.mjs +164 -0
- package/assets/skills/oat-project-dispatch-subagents/SKILL.md +24 -1
- package/assets/skills/oat-project-document/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-implement/references/dispatch-and-dry-run.md +11 -0
- package/assets/skills/oat-project-implement/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-plan-writing/SKILL.md +12 -1
- package/assets/skills/oat-project-pr-final/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-quick-start/references/docs/autonomy-contract.md +3 -3
- package/assets/skills/oat-project-review-provide/SKILL.md +12 -1
- package/assets/skills/oat-project-review-provide-remote/SKILL.md +12 -1
- package/dist/agents/canonical/index.d.ts +2 -0
- package/dist/agents/canonical/index.d.ts.map +1 -1
- package/dist/agents/canonical/index.js +1 -0
- package/dist/agents/canonical/resolve.d.ts +45 -0
- package/dist/agents/canonical/resolve.d.ts.map +1 -0
- package/dist/agents/canonical/resolve.js +175 -0
- package/dist/commands/decision/agents-guidance.d.ts +2 -2
- package/dist/commands/decision/agents-guidance.d.ts.map +1 -1
- package/dist/commands/decision/agents-guidance.js +1 -4
- package/dist/commands/decision/index.d.ts.map +1 -1
- package/dist/commands/decision/index.js +25 -6
- package/dist/commands/docs/init/index.d.ts +7 -1
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +53 -20
- package/dist/commands/doctor/index.d.ts +8 -2
- package/dist/commands/doctor/index.d.ts.map +1 -1
- package/dist/commands/doctor/index.js +157 -46
- package/dist/commands/init/index.d.ts +8 -3
- package/dist/commands/init/index.d.ts.map +1 -1
- package/dist/commands/init/index.js +64 -26
- package/dist/commands/init/tools/index.d.ts +12 -12
- package/dist/commands/init/tools/index.d.ts.map +1 -1
- package/dist/commands/init/tools/index.js +430 -99
- package/dist/commands/init/tools/install-state.d.ts +2 -0
- package/dist/commands/init/tools/install-state.d.ts.map +1 -1
- package/dist/commands/init/tools/install-state.js +11 -0
- package/dist/commands/init/tools/project-guidance.d.ts +49 -0
- package/dist/commands/init/tools/project-guidance.d.ts.map +1 -0
- package/dist/commands/init/tools/project-guidance.js +144 -0
- package/dist/commands/init/tools/workflows/index.d.ts +7 -0
- package/dist/commands/init/tools/workflows/index.d.ts.map +1 -1
- package/dist/commands/init/tools/workflows/index.js +160 -7
- package/dist/commands/pjm/index.d.ts.map +1 -1
- package/dist/commands/pjm/index.js +28 -3
- package/dist/commands/pjm/init.d.ts +5 -0
- package/dist/commands/pjm/init.d.ts.map +1 -1
- package/dist/commands/pjm/init.js +19 -3
- package/dist/commands/project/archive/archive-utils.d.ts +8 -1
- package/dist/commands/project/archive/archive-utils.d.ts.map +1 -1
- package/dist/commands/project/archive/archive-utils.js +147 -50
- package/dist/commands/project/archive/push-runner.d.ts.map +1 -1
- package/dist/commands/project/archive/push-runner.js +15 -2
- package/dist/commands/project/dispatch/index.d.ts +10 -0
- package/dist/commands/project/dispatch/index.d.ts.map +1 -0
- package/dist/commands/project/dispatch/index.js +137 -0
- package/dist/commands/project/dispatch/record.d.ts +91 -0
- package/dist/commands/project/dispatch/record.d.ts.map +1 -0
- package/dist/commands/project/dispatch/record.js +402 -0
- package/dist/commands/project/index.d.ts.map +1 -1
- package/dist/commands/project/index.js +2 -0
- package/dist/commands/project/links/compute.d.ts +1 -0
- package/dist/commands/project/links/compute.d.ts.map +1 -1
- package/dist/commands/project/links/compute.js +5 -4
- package/dist/commands/project/links/index.d.ts +9 -0
- package/dist/commands/project/links/index.d.ts.map +1 -1
- package/dist/commands/project/links/index.js +71 -2
- package/dist/commands/project/list.d.ts +10 -2
- package/dist/commands/project/list.d.ts.map +1 -1
- package/dist/commands/project/list.js +205 -29
- package/dist/commands/project/open/index.d.ts +2 -0
- package/dist/commands/project/open/index.d.ts.map +1 -1
- package/dist/commands/project/open/index.js +16 -1
- package/dist/commands/project/prune/index.d.ts +10 -4
- package/dist/commands/project/prune/index.d.ts.map +1 -1
- package/dist/commands/project/prune/index.js +85 -15
- package/dist/commands/project/pull/index.d.ts +4 -0
- package/dist/commands/project/pull/index.d.ts.map +1 -1
- package/dist/commands/project/pull/index.js +82 -3
- package/dist/commands/project/sync/git.d.ts +9 -0
- package/dist/commands/project/sync/git.d.ts.map +1 -1
- package/dist/commands/project/sync/git.js +18 -0
- package/dist/commands/project/sync/ref-sync.d.ts +16 -1
- package/dist/commands/project/sync/ref-sync.d.ts.map +1 -1
- package/dist/commands/project/sync/ref-sync.js +288 -17
- package/dist/commands/project/sync/resolve-target.d.ts +10 -0
- package/dist/commands/project/sync/resolve-target.d.ts.map +1 -1
- package/dist/commands/project/sync/resolve-target.js +56 -1
- package/dist/commands/providers/inspect/inspect.d.ts +8 -1
- package/dist/commands/providers/inspect/inspect.d.ts.map +1 -1
- package/dist/commands/providers/inspect/inspect.js +146 -26
- package/dist/commands/providers/list/list.d.ts +8 -1
- package/dist/commands/providers/list/list.d.ts.map +1 -1
- package/dist/commands/providers/list/list.js +139 -23
- package/dist/commands/providers/providers.types.d.ts +25 -1
- package/dist/commands/providers/providers.types.d.ts.map +1 -1
- package/dist/commands/providers/set/index.d.ts +9 -1
- package/dist/commands/providers/set/index.d.ts.map +1 -1
- package/dist/commands/providers/set/index.js +43 -33
- package/dist/commands/remove/skill/remove-skill.d.ts.map +1 -1
- package/dist/commands/remove/skill/remove-skill.js +11 -0
- package/dist/commands/shared/agents-md.d.ts +42 -14
- package/dist/commands/shared/agents-md.d.ts.map +1 -1
- package/dist/commands/shared/agents-md.js +364 -70
- package/dist/commands/shared/project-scope.d.ts +2 -0
- package/dist/commands/shared/project-scope.d.ts.map +1 -1
- package/dist/commands/shared/project-scope.js +5 -0
- package/dist/commands/state/generate.d.ts +2 -0
- package/dist/commands/state/generate.d.ts.map +1 -1
- package/dist/commands/state/generate.js +93 -28
- package/dist/commands/status/index.d.ts +8 -3
- package/dist/commands/status/index.d.ts.map +1 -1
- package/dist/commands/status/index.js +147 -32
- package/dist/commands/sync/apply.d.ts.map +1 -1
- package/dist/commands/sync/apply.js +220 -29
- package/dist/commands/sync/dry-run.d.ts.map +1 -1
- package/dist/commands/sync/dry-run.js +30 -6
- package/dist/commands/sync/index.d.ts +17 -2
- package/dist/commands/sync/index.d.ts.map +1 -1
- package/dist/commands/sync/index.js +106 -41
- package/dist/commands/sync/sync.types.d.ts +39 -2
- package/dist/commands/sync/sync.types.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.d.ts +5 -1
- package/dist/commands/sync/sync.utils.d.ts.map +1 -1
- package/dist/commands/sync/sync.utils.js +73 -0
- package/dist/commands/tools/info/info-tool.d.ts +2 -0
- package/dist/commands/tools/info/info-tool.d.ts.map +1 -1
- package/dist/commands/tools/info/info-tool.js +34 -12
- package/dist/commands/tools/install/index.d.ts.map +1 -1
- package/dist/commands/tools/install/index.js +19 -3
- package/dist/commands/tools/list/list-tools.d.ts +2 -0
- package/dist/commands/tools/list/list-tools.d.ts.map +1 -1
- package/dist/commands/tools/list/list-tools.js +36 -7
- package/dist/commands/tools/remove/index.d.ts.map +1 -1
- package/dist/commands/tools/remove/index.js +150 -21
- package/dist/commands/tools/remove/remove-tools.d.ts +20 -0
- package/dist/commands/tools/remove/remove-tools.d.ts.map +1 -1
- package/dist/commands/tools/remove/remove-tools.js +122 -1
- package/dist/commands/tools/shared/format-pack-inventory.d.ts +19 -0
- package/dist/commands/tools/shared/format-pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/format-pack-inventory.js +109 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts +66 -0
- package/dist/commands/tools/shared/pack-evidence.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-evidence.js +132 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts +1 -0
- package/dist/commands/tools/shared/pack-inventory.d.ts.map +1 -1
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts +44 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.d.ts.map +1 -0
- package/dist/commands/tools/shared/pack-lifecycle-outcome.js +91 -0
- package/dist/commands/tools/update/index.d.ts.map +1 -1
- package/dist/commands/tools/update/index.js +74 -4
- package/dist/commands/tools/update/update-tools.d.ts +5 -0
- package/dist/commands/tools/update/update-tools.d.ts.map +1 -1
- package/dist/commands/tools/update/update-tools.js +64 -2
- package/dist/config/oat-config.d.ts +5 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +17 -5
- package/dist/config/user-sync-config.d.ts +1 -0
- package/dist/config/user-sync-config.d.ts.map +1 -1
- package/dist/config/user-sync-config.js +8 -0
- package/dist/drift/detector.d.ts +2 -2
- package/dist/drift/detector.d.ts.map +1 -1
- package/dist/drift/detector.js +18 -0
- package/dist/drift/strays.d.ts.map +1 -1
- package/dist/drift/strays.js +5 -0
- package/dist/engine/collection-sync.d.ts +14 -0
- package/dist/engine/collection-sync.d.ts.map +1 -0
- package/dist/engine/collection-sync.js +282 -0
- package/dist/engine/compute-plan.d.ts +8 -1
- package/dist/engine/compute-plan.d.ts.map +1 -1
- package/dist/engine/compute-plan.js +303 -12
- package/dist/engine/engine.types.d.ts +61 -0
- package/dist/engine/engine.types.d.ts.map +1 -1
- package/dist/engine/execute-plan.d.ts +22 -2
- package/dist/engine/execute-plan.d.ts.map +1 -1
- package/dist/engine/execute-plan.js +459 -27
- package/dist/engine/provider-path-safety.d.ts +1 -0
- package/dist/engine/provider-path-safety.d.ts.map +1 -1
- package/dist/engine/provider-path-safety.js +15 -0
- package/dist/engine/scanner.d.ts +2 -2
- package/dist/engine/scanner.d.ts.map +1 -1
- package/dist/engine/scanner.js +21 -4
- package/dist/fs/io.d.ts +67 -0
- package/dist/fs/io.d.ts.map +1 -1
- package/dist/fs/io.js +536 -3
- package/dist/manifest/index.d.ts +2 -2
- package/dist/manifest/index.d.ts.map +1 -1
- package/dist/manifest/index.js +1 -1
- package/dist/manifest/manager.d.ts +2 -2
- package/dist/manifest/manager.d.ts.map +1 -1
- package/dist/manifest/manager.js +20 -3
- package/dist/manifest/manifest.types.d.ts +704 -13
- package/dist/manifest/manifest.types.d.ts.map +1 -1
- package/dist/manifest/manifest.types.js +131 -15
- package/dist/providers/codex/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/codex/codec/sync-extension.js +41 -10
- package/dist/providers/cursor/codec/sync-extension.d.ts.map +1 -1
- package/dist/providers/cursor/codec/sync-extension.js +41 -10
- package/dist/providers/identity/absolute-paths.d.ts +68 -0
- package/dist/providers/identity/absolute-paths.d.ts.map +1 -0
- package/dist/providers/identity/absolute-paths.js +144 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts +105 -0
- package/dist/providers/identity/claude-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts +40 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/claude-runtime-observation.fixtures.js +146 -0
- package/dist/providers/identity/claude-runtime-observation.js +229 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts +75 -0
- package/dist/providers/identity/codex-runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts +37 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.d.ts.map +1 -0
- package/dist/providers/identity/codex-runtime-observation.fixtures.js +539 -0
- package/dist/providers/identity/codex-runtime-observation.js +255 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts +313 -0
- package/dist/providers/identity/generic-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/generic-dispatch-record.js +539 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts +1964 -0
- package/dist/providers/identity/oat-dispatch-record.d.ts.map +1 -0
- package/dist/providers/identity/oat-dispatch-record.js +691 -0
- package/dist/providers/identity/runtime-observation.d.ts +100 -0
- package/dist/providers/identity/runtime-observation.d.ts.map +1 -0
- package/dist/providers/identity/runtime-observation.js +169 -0
- package/dist/providers/shared/index.d.ts +2 -0
- package/dist/providers/shared/index.d.ts.map +1 -1
- package/dist/providers/shared/index.js +1 -0
- package/dist/providers/shared/materialization-extension.d.ts +12 -0
- package/dist/providers/shared/materialization-extension.d.ts.map +1 -1
- package/dist/providers/shared/registry.d.ts +69 -0
- package/dist/providers/shared/registry.d.ts.map +1 -0
- package/dist/providers/shared/registry.js +252 -0
- package/dist/providers/shared/restart-adviser.d.ts +26 -0
- package/dist/providers/shared/restart-adviser.d.ts.map +1 -0
- package/dist/providers/shared/restart-adviser.js +96 -0
- package/dist/shared/types.d.ts +4 -0
- package/dist/shared/types.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude runtime metadata parsing.
|
|
3
|
+
*
|
|
4
|
+
* Field paths here are taken from real on-disk transcripts under
|
|
5
|
+
* `~/.claude/projects/`, not from assumption. Every corpus figure in this file
|
|
6
|
+
* is an operator-environment observation as of 2026-09-02 on the capturing
|
|
7
|
+
* operator's machine, not a provider guarantee: a later mismatch means the
|
|
8
|
+
* corpus moved, not that the claim was wrong.
|
|
9
|
+
*
|
|
10
|
+
* An earlier revision read only `system`/`init` and `result` records; a scan of
|
|
11
|
+
* all 2,725 local transcripts found `"subtype":"init"` in zero of them, so that parser returned
|
|
12
|
+
* `not-reported` against every real transcript while its hand-written fixtures
|
|
13
|
+
* agreed with it. The on-disk `assistant` entry is now the primary shape.
|
|
14
|
+
*
|
|
15
|
+
* Reading an `assistant` entry does not mean reading a conversation. The parser
|
|
16
|
+
* takes allowlisted entry-level metadata plus exactly two explicit key paths
|
|
17
|
+
* inside `message` — `message.model` and `message.usage.service_tier`.
|
|
18
|
+
* `message` is never spread, enumerated, or filtered after the fact, so
|
|
19
|
+
* `message.content` is not merely dropped later; it is never reached. The
|
|
20
|
+
* content-trap test pins this: a `message` whose `content` throws on access
|
|
21
|
+
* still parses cleanly.
|
|
22
|
+
*
|
|
23
|
+
* Everything this module produces is per-run, non-authoritative corroboration.
|
|
24
|
+
* A failed or partial parse yields `not-reported` and never falls back to the
|
|
25
|
+
* configured invocation.
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* The complete entry-level read surface for an `assistant` entry. `message` is
|
|
29
|
+
* handled separately by explicit path and is deliberately absent from this
|
|
30
|
+
* list, so this plus `message.model` and `message.usage.service_tier` is
|
|
31
|
+
* everything the parser touches. Exported so a test can pin it: a future widening
|
|
32
|
+
* has to change this list, in view, rather than slip in at a call site.
|
|
33
|
+
*
|
|
34
|
+
* `attributionAgent` is the role identifier and is the same class of signal
|
|
35
|
+
* Codex carries as `agent_role`: a bounded enum-like name, not conversation
|
|
36
|
+
* content. Across 2,725 captured transcripts it took 8 distinct values, all
|
|
37
|
+
* of which pass the shared identifier validator, with a longest value of 21
|
|
38
|
+
* characters against the 256 bound. It appears on subagent turns only, so a
|
|
39
|
+
* main session reports no role rather than a synthesized one.
|
|
40
|
+
*/
|
|
41
|
+
export declare const CLAUDE_ASSISTANT_KEYS: readonly ['type', 'isSidechain', 'effort', 'attributionAgent', 'sessionId', 'session_id', 'requestId'];
|
|
42
|
+
/**
|
|
43
|
+
* Stream-json entry keys, for `claude -p --output-format stream-json`.
|
|
44
|
+
*
|
|
45
|
+
* UNVERIFIED: no captured artifact of that format was available, and zero of
|
|
46
|
+
* the 2,725 observed local transcripts contained a `system`/`init` record. This path is
|
|
47
|
+
* retained as a secondary shape and must not be presented as equally grounded
|
|
48
|
+
* with the on-disk shape above.
|
|
49
|
+
*/
|
|
50
|
+
export declare const CLAUDE_INIT_KEYS: readonly ['type', 'subtype', 'model', 'service_tier', 'serviceTier', 'agent', 'subagent_type', 'reasoning_effort', 'effort', 'request_id'];
|
|
51
|
+
export declare const CLAUDE_OBSERVATION_SOURCE = "claude-session-metadata";
|
|
52
|
+
export interface ClaudeRuntimeMetadata {
|
|
53
|
+
/**
|
|
54
|
+
* `root` for a main session, `depth-unknown` for a subagent turn.
|
|
55
|
+
*
|
|
56
|
+
* `isSidechain` is the only lineage signal Claude emits and it is binary. No
|
|
57
|
+
* depth, nesting, level, or ancestry key appeared on any of the 141,078
|
|
58
|
+
* observed assistant entries, and `parentUuid` never crosses an `agentId`
|
|
59
|
+
* boundary, so it chains messages within one agent rather than agents to
|
|
60
|
+
* each other. A depth number is therefore not derivable and is not invented.
|
|
61
|
+
*/
|
|
62
|
+
childLineage: string | null;
|
|
63
|
+
/** Observed role, from `attributionAgent`; `null` when the run reports none. */
|
|
64
|
+
role: string | null;
|
|
65
|
+
model: string | null;
|
|
66
|
+
effort: string | null;
|
|
67
|
+
serviceTier: string | null;
|
|
68
|
+
/**
|
|
69
|
+
* OAT request correlation declared by the provider, for parity with the Codex
|
|
70
|
+
* parser. Claude declares none, so this is `null` on a real transcript.
|
|
71
|
+
* Claude's own `requestId` is a per-turn API identifier and its `sessionId` a
|
|
72
|
+
* transcript identifier; neither is an OAT dispatch request id, so neither is
|
|
73
|
+
* equality-checked against one.
|
|
74
|
+
*/
|
|
75
|
+
requestId: string | null;
|
|
76
|
+
/** Provider session identifier, used to prove the envelope is one session. */
|
|
77
|
+
sessionId: string | null;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Extract the child's metadata from Claude transcript entries.
|
|
81
|
+
*
|
|
82
|
+
* The applicable turn is the last one: it is the most recent state the session
|
|
83
|
+
* reported. Earlier turns fill only the fields the last one left unreported.
|
|
84
|
+
* Returns `null` when no Claude metadata is present, or when the entries mix
|
|
85
|
+
* sessions — every captured transcript carries exactly one `sessionId`, so more
|
|
86
|
+
* than one means no single applicable child exists.
|
|
87
|
+
*/
|
|
88
|
+
export declare function extractClaudeRuntimeMetadata(entries: readonly unknown[]): ClaudeRuntimeMetadata | null;
|
|
89
|
+
/**
|
|
90
|
+
* Neutral observation facts for the cross-provider projection.
|
|
91
|
+
*
|
|
92
|
+
* The single-session guarantee runs in-process inside
|
|
93
|
+
* {@link extractClaudeRuntimeMetadata}, so `sessionId` never needs to survive
|
|
94
|
+
* into the projected output — which matters, because `sessionId` classifies
|
|
95
|
+
* sensitive and previously made every real transcript unrecordable.
|
|
96
|
+
*/
|
|
97
|
+
export declare function observeClaudeRuntimeFacts(entries: readonly unknown[]): {
|
|
98
|
+
lineage: string | null;
|
|
99
|
+
role: string | null;
|
|
100
|
+
model: string | null;
|
|
101
|
+
effort: string | null;
|
|
102
|
+
serviceTier: string | null;
|
|
103
|
+
correlation: string | null;
|
|
104
|
+
} | null;
|
|
105
|
+
//# sourceMappingURL=claude-runtime-observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-runtime-observation.d.ts","sourceRoot":"","sources":["../../../src/providers/identity/claude-runtime-observation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,YAChC,MAAM,EACN,aAAa,EACb,QAAQ,EACR,kBAAkB,EAClB,WAAW,EACX,YAAY,EACZ,WAAW,CACH,CAAC;AAEX;;;;;;;GAOG;AACH,eAAO,MAAM,gBAAgB,YAC3B,MAAM,EACN,SAAS,EACT,OAAO,EACP,cAAc,EACd,aAAa,EACb,OAAO,EACP,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,YAAY,CACJ,CAAC;AAEX,eAAO,MAAM,yBAAyB,4BAA4B,CAAC;AAEnE,MAAM,WAAW,qBAAqB;IACpC;;;;;;;;OAQG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,gFAAgF;IAChF,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B;;;;;;OAMG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8EAA8E;IAC9E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AA+FD;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,qBAAqB,GAAG,IAAI,CAmD9B;AAED;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG;IACtE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,IAAI,CAWP"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captured Claude transcript metadata, sanitized.
|
|
3
|
+
*
|
|
4
|
+
* Derived from real on-disk transcripts under `~/.claude/projects/`, which is
|
|
5
|
+
* the format Claude actually writes. Corpus counts below are
|
|
6
|
+
* operator-environment observations (as of 2026-09-02, on the capturing operator's machine). They replaced hand-written fixtures built
|
|
7
|
+
* around `system`/`init` and `result` records: a scan of all 2,725 local
|
|
8
|
+
* transcripts found `"subtype":"init"` in zero of them, so the previous parser
|
|
9
|
+
* returned `not-reported` against every real transcript while its own fixtures
|
|
10
|
+
* agreed with it.
|
|
11
|
+
*
|
|
12
|
+
* Sanitization is allowlist-based. Retained: the entry-level metadata keys the
|
|
13
|
+
* parser reads plus a few it does not (`version`, `userType`, `uuid`), so the
|
|
14
|
+
* fixtures still demonstrate that unread keys are dropped. `message` is reduced
|
|
15
|
+
* to the two explicit key paths the parser reaches — `message.model` and
|
|
16
|
+
* `message.usage.service_tier`. Dropped outright: `message.content` (the
|
|
17
|
+
* conversation), `cwd`, `gitBranch`, `slug`, `agentId`, and the remaining
|
|
18
|
+
* `attribution*` fields.
|
|
19
|
+
*
|
|
20
|
+
* Structural facts these fixtures preserve, each load-bearing:
|
|
21
|
+
* - `effort` is a real top-level field on an assistant entry. Claude does
|
|
22
|
+
* expose a selectable effort axis, so reporting `not-exposed` for it was
|
|
23
|
+
* wrong; observed values across 124,804 entries are `high`, `xhigh`,
|
|
24
|
+
* `medium`, and `max`.
|
|
25
|
+
* - `attributionAgent` is the role identifier, and it is exactly the signal
|
|
26
|
+
* Codex carries as `agent_role`. It appears on subagent turns only: present
|
|
27
|
+
* on 114,600 of 114,657 sidechain entries and on none of the 26,497
|
|
28
|
+
* main-session entries. `SIDECHAIN_TRANSCRIPT` therefore carries it and
|
|
29
|
+
* `MAIN_SESSION_TRANSCRIPT` does not, which is the real distinction rather
|
|
30
|
+
* than a constructed one.
|
|
31
|
+
* - `isSidechain` distinguishes a main session from a subagent turn. It is the
|
|
32
|
+
* only lineage signal present, and it is binary. Role names are not a depth
|
|
33
|
+
* signal and are never read as one.
|
|
34
|
+
* - `sessionId` is constant within a transcript; every one of the 2,655 local
|
|
35
|
+
* transcripts that carries one carries exactly one.
|
|
36
|
+
* - Model and service tier live only under `message`, never at the top level.
|
|
37
|
+
*/
|
|
38
|
+
export declare const MAIN_SESSION_TRANSCRIPT: readonly unknown[];
|
|
39
|
+
export declare const SIDECHAIN_TRANSCRIPT: readonly unknown[];
|
|
40
|
+
//# sourceMappingURL=claude-runtime-observation.fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"claude-runtime-observation.fixtures.d.ts","sourceRoot":"","sources":["../../../src/providers/identity/claude-runtime-observation.fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AAEH,eAAO,MAAM,uBAAuB,EAAE,SAAS,OAAO,EAoDrD,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,SAAS,OAAO,EAuDlD,CAAC"}
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captured Claude transcript metadata, sanitized.
|
|
3
|
+
*
|
|
4
|
+
* Derived from real on-disk transcripts under `~/.claude/projects/`, which is
|
|
5
|
+
* the format Claude actually writes. Corpus counts below are
|
|
6
|
+
* operator-environment observations (as of 2026-09-02, on the capturing operator's machine). They replaced hand-written fixtures built
|
|
7
|
+
* around `system`/`init` and `result` records: a scan of all 2,725 local
|
|
8
|
+
* transcripts found `"subtype":"init"` in zero of them, so the previous parser
|
|
9
|
+
* returned `not-reported` against every real transcript while its own fixtures
|
|
10
|
+
* agreed with it.
|
|
11
|
+
*
|
|
12
|
+
* Sanitization is allowlist-based. Retained: the entry-level metadata keys the
|
|
13
|
+
* parser reads plus a few it does not (`version`, `userType`, `uuid`), so the
|
|
14
|
+
* fixtures still demonstrate that unread keys are dropped. `message` is reduced
|
|
15
|
+
* to the two explicit key paths the parser reaches — `message.model` and
|
|
16
|
+
* `message.usage.service_tier`. Dropped outright: `message.content` (the
|
|
17
|
+
* conversation), `cwd`, `gitBranch`, `slug`, `agentId`, and the remaining
|
|
18
|
+
* `attribution*` fields.
|
|
19
|
+
*
|
|
20
|
+
* Structural facts these fixtures preserve, each load-bearing:
|
|
21
|
+
* - `effort` is a real top-level field on an assistant entry. Claude does
|
|
22
|
+
* expose a selectable effort axis, so reporting `not-exposed` for it was
|
|
23
|
+
* wrong; observed values across 124,804 entries are `high`, `xhigh`,
|
|
24
|
+
* `medium`, and `max`.
|
|
25
|
+
* - `attributionAgent` is the role identifier, and it is exactly the signal
|
|
26
|
+
* Codex carries as `agent_role`. It appears on subagent turns only: present
|
|
27
|
+
* on 114,600 of 114,657 sidechain entries and on none of the 26,497
|
|
28
|
+
* main-session entries. `SIDECHAIN_TRANSCRIPT` therefore carries it and
|
|
29
|
+
* `MAIN_SESSION_TRANSCRIPT` does not, which is the real distinction rather
|
|
30
|
+
* than a constructed one.
|
|
31
|
+
* - `isSidechain` distinguishes a main session from a subagent turn. It is the
|
|
32
|
+
* only lineage signal present, and it is binary. Role names are not a depth
|
|
33
|
+
* signal and are never read as one.
|
|
34
|
+
* - `sessionId` is constant within a transcript; every one of the 2,655 local
|
|
35
|
+
* transcripts that carries one carries exactly one.
|
|
36
|
+
* - Model and service tier live only under `message`, never at the top level.
|
|
37
|
+
*/
|
|
38
|
+
export const MAIN_SESSION_TRANSCRIPT = [
|
|
39
|
+
{
|
|
40
|
+
type: 'assistant',
|
|
41
|
+
isSidechain: false,
|
|
42
|
+
effort: 'high',
|
|
43
|
+
sessionId: '7f9d5ab4-3b08-4a21-adb5-405c04af2d89',
|
|
44
|
+
requestId: 'req_011Ce9GB4DvzreK2hzChvmgy',
|
|
45
|
+
uuid: '14c99a81-02ff-4153-8104-3e4d238451f9',
|
|
46
|
+
parentUuid: '66d090ee-2e16-4b8d-bc67-bcb1027220cb',
|
|
47
|
+
version: '2.1.234',
|
|
48
|
+
userType: 'external',
|
|
49
|
+
message: {
|
|
50
|
+
model: 'claude-fable-5',
|
|
51
|
+
usage: {
|
|
52
|
+
service_tier: 'standard',
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
type: 'assistant',
|
|
58
|
+
isSidechain: false,
|
|
59
|
+
effort: 'high',
|
|
60
|
+
sessionId: '7f9d5ab4-3b08-4a21-adb5-405c04af2d89',
|
|
61
|
+
requestId: 'req_011Ce9GB4DvzreK2hzChvmgy',
|
|
62
|
+
uuid: '50ef9865-24e6-4a77-9831-a01258db757f',
|
|
63
|
+
parentUuid: '14c99a81-02ff-4153-8104-3e4d238451f9',
|
|
64
|
+
version: '2.1.234',
|
|
65
|
+
userType: 'external',
|
|
66
|
+
message: {
|
|
67
|
+
model: 'claude-fable-5',
|
|
68
|
+
usage: {
|
|
69
|
+
service_tier: 'standard',
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
type: 'assistant',
|
|
75
|
+
isSidechain: false,
|
|
76
|
+
effort: 'high',
|
|
77
|
+
sessionId: '7f9d5ab4-3b08-4a21-adb5-405c04af2d89',
|
|
78
|
+
requestId: 'req_011Ce9GB4DvzreK2hzChvmgy',
|
|
79
|
+
uuid: '15864101-70c5-48fb-939f-679a458ba679',
|
|
80
|
+
parentUuid: '50ef9865-24e6-4a77-9831-a01258db757f',
|
|
81
|
+
version: '2.1.234',
|
|
82
|
+
userType: 'external',
|
|
83
|
+
message: {
|
|
84
|
+
model: 'claude-fable-5',
|
|
85
|
+
usage: {
|
|
86
|
+
service_tier: 'standard',
|
|
87
|
+
},
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
];
|
|
91
|
+
export const SIDECHAIN_TRANSCRIPT = [
|
|
92
|
+
{
|
|
93
|
+
type: 'assistant',
|
|
94
|
+
isSidechain: true,
|
|
95
|
+
effort: 'high',
|
|
96
|
+
attributionAgent: 'general-purpose',
|
|
97
|
+
sessionId: '19c78382-cceb-45ab-bf24-bb8aa284d96b',
|
|
98
|
+
requestId: 'req_011CdSgeEdPwRsUpVTCihKmV',
|
|
99
|
+
uuid: '0f106449-eeb9-475c-8186-d70b9d14a82c',
|
|
100
|
+
parentUuid: '95017f46-0284-49e3-9a7c-597ad4364042',
|
|
101
|
+
version: '2.1.220',
|
|
102
|
+
userType: 'external',
|
|
103
|
+
message: {
|
|
104
|
+
model: 'claude-opus-5',
|
|
105
|
+
usage: {
|
|
106
|
+
service_tier: 'standard',
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
type: 'assistant',
|
|
112
|
+
isSidechain: true,
|
|
113
|
+
effort: 'high',
|
|
114
|
+
attributionAgent: 'general-purpose',
|
|
115
|
+
sessionId: '19c78382-cceb-45ab-bf24-bb8aa284d96b',
|
|
116
|
+
requestId: 'req_011CdSgeEdPwRsUpVTCihKmV',
|
|
117
|
+
uuid: '24c36d1b-c532-447f-9981-8f2b0d0988f8',
|
|
118
|
+
parentUuid: '0f106449-eeb9-475c-8186-d70b9d14a82c',
|
|
119
|
+
version: '2.1.220',
|
|
120
|
+
userType: 'external',
|
|
121
|
+
message: {
|
|
122
|
+
model: 'claude-opus-5',
|
|
123
|
+
usage: {
|
|
124
|
+
service_tier: 'standard',
|
|
125
|
+
},
|
|
126
|
+
},
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
type: 'assistant',
|
|
130
|
+
isSidechain: true,
|
|
131
|
+
effort: 'high',
|
|
132
|
+
attributionAgent: 'general-purpose',
|
|
133
|
+
sessionId: '19c78382-cceb-45ab-bf24-bb8aa284d96b',
|
|
134
|
+
requestId: 'req_011CdSgeEdPwRsUpVTCihKmV',
|
|
135
|
+
uuid: 'd3453335-a00b-4716-95bf-6a7574903336',
|
|
136
|
+
parentUuid: 'c0d14665-a467-46e5-abcd-85c3e15ba30e',
|
|
137
|
+
version: '2.1.220',
|
|
138
|
+
userType: 'external',
|
|
139
|
+
message: {
|
|
140
|
+
model: 'claude-opus-5',
|
|
141
|
+
usage: {
|
|
142
|
+
service_tier: 'standard',
|
|
143
|
+
},
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
];
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import { observationIdentifier as observedValue } from './oat-dispatch-record.js';
|
|
2
|
+
/**
|
|
3
|
+
* Claude runtime metadata parsing.
|
|
4
|
+
*
|
|
5
|
+
* Field paths here are taken from real on-disk transcripts under
|
|
6
|
+
* `~/.claude/projects/`, not from assumption. Every corpus figure in this file
|
|
7
|
+
* is an operator-environment observation as of 2026-09-02 on the capturing
|
|
8
|
+
* operator's machine, not a provider guarantee: a later mismatch means the
|
|
9
|
+
* corpus moved, not that the claim was wrong.
|
|
10
|
+
*
|
|
11
|
+
* An earlier revision read only `system`/`init` and `result` records; a scan of
|
|
12
|
+
* all 2,725 local transcripts found `"subtype":"init"` in zero of them, so that parser returned
|
|
13
|
+
* `not-reported` against every real transcript while its hand-written fixtures
|
|
14
|
+
* agreed with it. The on-disk `assistant` entry is now the primary shape.
|
|
15
|
+
*
|
|
16
|
+
* Reading an `assistant` entry does not mean reading a conversation. The parser
|
|
17
|
+
* takes allowlisted entry-level metadata plus exactly two explicit key paths
|
|
18
|
+
* inside `message` — `message.model` and `message.usage.service_tier`.
|
|
19
|
+
* `message` is never spread, enumerated, or filtered after the fact, so
|
|
20
|
+
* `message.content` is not merely dropped later; it is never reached. The
|
|
21
|
+
* content-trap test pins this: a `message` whose `content` throws on access
|
|
22
|
+
* still parses cleanly.
|
|
23
|
+
*
|
|
24
|
+
* Everything this module produces is per-run, non-authoritative corroboration.
|
|
25
|
+
* A failed or partial parse yields `not-reported` and never falls back to the
|
|
26
|
+
* configured invocation.
|
|
27
|
+
*/
|
|
28
|
+
/**
|
|
29
|
+
* The complete entry-level read surface for an `assistant` entry. `message` is
|
|
30
|
+
* handled separately by explicit path and is deliberately absent from this
|
|
31
|
+
* list, so this plus `message.model` and `message.usage.service_tier` is
|
|
32
|
+
* everything the parser touches. Exported so a test can pin it: a future widening
|
|
33
|
+
* has to change this list, in view, rather than slip in at a call site.
|
|
34
|
+
*
|
|
35
|
+
* `attributionAgent` is the role identifier and is the same class of signal
|
|
36
|
+
* Codex carries as `agent_role`: a bounded enum-like name, not conversation
|
|
37
|
+
* content. Across 2,725 captured transcripts it took 8 distinct values, all
|
|
38
|
+
* of which pass the shared identifier validator, with a longest value of 21
|
|
39
|
+
* characters against the 256 bound. It appears on subagent turns only, so a
|
|
40
|
+
* main session reports no role rather than a synthesized one.
|
|
41
|
+
*/
|
|
42
|
+
export const CLAUDE_ASSISTANT_KEYS = [
|
|
43
|
+
'type',
|
|
44
|
+
'isSidechain',
|
|
45
|
+
'effort',
|
|
46
|
+
'attributionAgent',
|
|
47
|
+
'sessionId',
|
|
48
|
+
'session_id',
|
|
49
|
+
'requestId',
|
|
50
|
+
];
|
|
51
|
+
/**
|
|
52
|
+
* Stream-json entry keys, for `claude -p --output-format stream-json`.
|
|
53
|
+
*
|
|
54
|
+
* UNVERIFIED: no captured artifact of that format was available, and zero of
|
|
55
|
+
* the 2,725 observed local transcripts contained a `system`/`init` record. This path is
|
|
56
|
+
* retained as a secondary shape and must not be presented as equally grounded
|
|
57
|
+
* with the on-disk shape above.
|
|
58
|
+
*/
|
|
59
|
+
export const CLAUDE_INIT_KEYS = [
|
|
60
|
+
'type',
|
|
61
|
+
'subtype',
|
|
62
|
+
'model',
|
|
63
|
+
'service_tier',
|
|
64
|
+
'serviceTier',
|
|
65
|
+
'agent',
|
|
66
|
+
'subagent_type',
|
|
67
|
+
'reasoning_effort',
|
|
68
|
+
'effort',
|
|
69
|
+
'request_id',
|
|
70
|
+
];
|
|
71
|
+
export const CLAUDE_OBSERVATION_SOURCE = 'claude-session-metadata';
|
|
72
|
+
function isRecord(value) {
|
|
73
|
+
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* The two explicit key paths inside `message`. Reaching them by path is what
|
|
77
|
+
* makes the projection narrow; a spread or key-filter would touch
|
|
78
|
+
* `message.content` on the way.
|
|
79
|
+
*/
|
|
80
|
+
function messageMetadata(entry) {
|
|
81
|
+
const message = entry.message;
|
|
82
|
+
if (!isRecord(message))
|
|
83
|
+
return { model: undefined, serviceTier: undefined };
|
|
84
|
+
const usage = message.usage;
|
|
85
|
+
return {
|
|
86
|
+
model: message.model,
|
|
87
|
+
serviceTier: isRecord(usage) ? usage.service_tier : undefined,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function firstModelUsage(entry) {
|
|
91
|
+
const usage = entry.modelUsage;
|
|
92
|
+
if (!isRecord(usage))
|
|
93
|
+
return null;
|
|
94
|
+
const [name, detail] = Object.entries(usage)[0] ?? [];
|
|
95
|
+
if (name === undefined)
|
|
96
|
+
return null;
|
|
97
|
+
return {
|
|
98
|
+
model: observedValue(name),
|
|
99
|
+
serviceTier: isRecord(detail)
|
|
100
|
+
? observedValue(detail.serviceTier ?? detail.service_tier)
|
|
101
|
+
: null,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
function assistantTurn(entry) {
|
|
105
|
+
const { model, serviceTier } = messageMetadata(entry);
|
|
106
|
+
return {
|
|
107
|
+
isSidechain: typeof entry.isSidechain === 'boolean' ? entry.isSidechain : null,
|
|
108
|
+
effort: observedValue(entry.effort),
|
|
109
|
+
sessionId: observedValue(entry.sessionId ?? entry.session_id),
|
|
110
|
+
model: observedValue(model),
|
|
111
|
+
serviceTier: observedValue(serviceTier),
|
|
112
|
+
requestId: null,
|
|
113
|
+
// Role only. It never contributes to lineage: `isSidechain` is the sole
|
|
114
|
+
// lineage signal, and inferring depth from a role name would be exactly
|
|
115
|
+
// the invention this parser was rewritten to remove.
|
|
116
|
+
role: observedValue(entry.attributionAgent),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
/** Secondary, unverified stream-json shape; see CLAUDE_INIT_KEYS. */
|
|
120
|
+
function streamJsonTurn(entry) {
|
|
121
|
+
if (entry.type === 'system' && entry.subtype === 'init') {
|
|
122
|
+
return {
|
|
123
|
+
isSidechain: null,
|
|
124
|
+
effort: observedValue(entry.reasoning_effort ?? entry.effort),
|
|
125
|
+
sessionId: null,
|
|
126
|
+
model: observedValue(entry.model),
|
|
127
|
+
serviceTier: observedValue(entry.service_tier ?? entry.serviceTier),
|
|
128
|
+
requestId: observedValue(entry.request_id),
|
|
129
|
+
role: observedValue(entry.agent ?? entry.subagent_type),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
if (entry.type === 'result') {
|
|
133
|
+
const usage = firstModelUsage(entry);
|
|
134
|
+
if (usage === null)
|
|
135
|
+
return null;
|
|
136
|
+
return {
|
|
137
|
+
isSidechain: null,
|
|
138
|
+
effort: null,
|
|
139
|
+
sessionId: null,
|
|
140
|
+
model: usage.model,
|
|
141
|
+
serviceTier: usage.serviceTier,
|
|
142
|
+
requestId: null,
|
|
143
|
+
role: null,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* Extract the child's metadata from Claude transcript entries.
|
|
150
|
+
*
|
|
151
|
+
* The applicable turn is the last one: it is the most recent state the session
|
|
152
|
+
* reported. Earlier turns fill only the fields the last one left unreported.
|
|
153
|
+
* Returns `null` when no Claude metadata is present, or when the entries mix
|
|
154
|
+
* sessions — every captured transcript carries exactly one `sessionId`, so more
|
|
155
|
+
* than one means no single applicable child exists.
|
|
156
|
+
*/
|
|
157
|
+
export function extractClaudeRuntimeMetadata(entries) {
|
|
158
|
+
if (!Array.isArray(entries))
|
|
159
|
+
return null;
|
|
160
|
+
const turns = [];
|
|
161
|
+
for (const entry of entries) {
|
|
162
|
+
if (!isRecord(entry))
|
|
163
|
+
continue;
|
|
164
|
+
// Classification is by discriminator alone.
|
|
165
|
+
if (entry.type === 'assistant') {
|
|
166
|
+
turns.push(assistantTurn(entry));
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
const fallback = streamJsonTurn(entry);
|
|
170
|
+
if (fallback !== null)
|
|
171
|
+
turns.push(fallback);
|
|
172
|
+
}
|
|
173
|
+
if (turns.length === 0)
|
|
174
|
+
return null;
|
|
175
|
+
const sessions = new Set(turns
|
|
176
|
+
.map((turn) => turn.sessionId)
|
|
177
|
+
.filter((value) => value !== null));
|
|
178
|
+
if (sessions.size > 1)
|
|
179
|
+
return null;
|
|
180
|
+
const applicable = turns.at(-1);
|
|
181
|
+
if (!applicable)
|
|
182
|
+
return null;
|
|
183
|
+
let model = null;
|
|
184
|
+
let effort = null;
|
|
185
|
+
let serviceTier = null;
|
|
186
|
+
let requestId = null;
|
|
187
|
+
let role = null;
|
|
188
|
+
for (const turn of turns) {
|
|
189
|
+
model = turn.model ?? model;
|
|
190
|
+
effort = turn.effort ?? effort;
|
|
191
|
+
serviceTier = turn.serviceTier ?? serviceTier;
|
|
192
|
+
requestId = turn.requestId ?? requestId;
|
|
193
|
+
role = turn.role ?? role;
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
childLineage: applicable.isSidechain === null
|
|
197
|
+
? null
|
|
198
|
+
: applicable.isSidechain
|
|
199
|
+
? 'depth-unknown'
|
|
200
|
+
: 'root',
|
|
201
|
+
role,
|
|
202
|
+
model,
|
|
203
|
+
effort,
|
|
204
|
+
serviceTier,
|
|
205
|
+
requestId,
|
|
206
|
+
sessionId: [...sessions][0] ?? null,
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Neutral observation facts for the cross-provider projection.
|
|
211
|
+
*
|
|
212
|
+
* The single-session guarantee runs in-process inside
|
|
213
|
+
* {@link extractClaudeRuntimeMetadata}, so `sessionId` never needs to survive
|
|
214
|
+
* into the projected output — which matters, because `sessionId` classifies
|
|
215
|
+
* sensitive and previously made every real transcript unrecordable.
|
|
216
|
+
*/
|
|
217
|
+
export function observeClaudeRuntimeFacts(entries) {
|
|
218
|
+
const metadata = extractClaudeRuntimeMetadata(entries);
|
|
219
|
+
if (metadata === null)
|
|
220
|
+
return null;
|
|
221
|
+
return {
|
|
222
|
+
lineage: metadata.childLineage,
|
|
223
|
+
role: metadata.role,
|
|
224
|
+
model: metadata.model,
|
|
225
|
+
effort: metadata.effort,
|
|
226
|
+
serviceTier: metadata.serviceTier,
|
|
227
|
+
correlation: metadata.requestId,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Codex rollout metadata parsing.
|
|
3
|
+
*
|
|
4
|
+
* Field paths here are taken from captured Codex 0.152.1 rollouts, not from
|
|
5
|
+
* assumption; see `codex-runtime-observation.fixtures.ts` for the sanitized
|
|
6
|
+
* captures the tests run against.
|
|
7
|
+
*
|
|
8
|
+
* Four accepted paths are UNVERIFIED against any captured rollout and appear
|
|
9
|
+
* zero times in the operator's local corpus (1,596 rollouts spanning cli_version
|
|
10
|
+
* 0.142.4-0.152.x, as of 2026-09-02, on the capturing operator's machine): `turn_context.service_tier`,
|
|
11
|
+
* `turn_context.serviceTier`, `turn_context.reasoning_effort`, and
|
|
12
|
+
* `session_meta.request_id`. They are retained as forward-compatible readers
|
|
13
|
+
* and all fail closed to `null`, so no Codex rollout observed to date reports a
|
|
14
|
+
* service tier, and Codex request correlation is caller-asserted in practice.
|
|
15
|
+
* They are labelled here for the same reason `CLAUDE_INIT_KEYS` is labelled:
|
|
16
|
+
* an unverified path must not read as a captured one. An earlier revision of this parser read
|
|
17
|
+
* `payload.parent_id` and `payload.role`, which Codex does not emit, so every
|
|
18
|
+
* subagent was misreported as a root with no role while hand-written fixtures
|
|
19
|
+
* agreed with the parser instead of with the world.
|
|
20
|
+
*
|
|
21
|
+
* The parser reads session and turn metadata only. Entries are classified by
|
|
22
|
+
* their `type` discriminator alone, and the payload of any entry outside
|
|
23
|
+
* {@link CODEX_METADATA_ENTRY_TYPES} is never touched, so conversation content,
|
|
24
|
+
* instructions, and tool output cannot be reached from here. Every extracted
|
|
25
|
+
* value is a short provider identifier validated against a closed shape before
|
|
26
|
+
* it can become durable evidence.
|
|
27
|
+
*
|
|
28
|
+
* Everything this module produces is per-run, non-authoritative corroboration.
|
|
29
|
+
* A failed or partial parse yields `not-reported`; it never falls back to the
|
|
30
|
+
* configured invocation, so a requested value cannot masquerade as an
|
|
31
|
+
* observation.
|
|
32
|
+
*/
|
|
33
|
+
/** Entry types whose payloads are metadata rather than conversation content. */
|
|
34
|
+
export declare const CODEX_METADATA_ENTRY_TYPES: readonly ['session_meta', 'turn_context'];
|
|
35
|
+
export declare const CODEX_OBSERVATION_SOURCE = "codex-rollout-metadata";
|
|
36
|
+
export interface CodexRuntimeMetadata {
|
|
37
|
+
childLineage: string;
|
|
38
|
+
role: string | null;
|
|
39
|
+
model: string | null;
|
|
40
|
+
effort: string | null;
|
|
41
|
+
serviceTier: string | null;
|
|
42
|
+
/** Request correlation declared by the session itself, when present. */
|
|
43
|
+
requestId: string | null;
|
|
44
|
+
/** Raw `thread_source`; `user` for a root session, `subagent` for a child. */
|
|
45
|
+
threadSource: string | null;
|
|
46
|
+
/**
|
|
47
|
+
* Raw `forked_from_id`. Recorded without interpretation: a subagent commonly
|
|
48
|
+
* carries it alongside `parent_thread_id`, so it does not by itself identify
|
|
49
|
+
* a user fork. See the module tests for what could and could not be
|
|
50
|
+
* established about fork shapes.
|
|
51
|
+
*/
|
|
52
|
+
forkedFromId: string | null;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Extract the applicable child's metadata from Codex rollout entries.
|
|
56
|
+
*
|
|
57
|
+
* The applicable session is the *first* `session_meta`: a rollout's own header
|
|
58
|
+
* is written at ordinal 0, and any embedded parent history follows it.
|
|
59
|
+
*/
|
|
60
|
+
export declare function extractCodexRuntimeMetadata(entries: readonly unknown[]): CodexRuntimeMetadata | null;
|
|
61
|
+
/**
|
|
62
|
+
* Neutral observation facts for the cross-provider projection.
|
|
63
|
+
*
|
|
64
|
+
* Nothing of the rollout's own shape escapes this module: the caller receives
|
|
65
|
+
* only the closed fact set owned by `runtime-observation.ts`.
|
|
66
|
+
*/
|
|
67
|
+
export declare function observeCodexRuntimeFacts(entries: readonly unknown[]): {
|
|
68
|
+
lineage: string | null;
|
|
69
|
+
role: string | null;
|
|
70
|
+
model: string | null;
|
|
71
|
+
effort: string | null;
|
|
72
|
+
serviceTier: string | null;
|
|
73
|
+
correlation: string | null;
|
|
74
|
+
} | null;
|
|
75
|
+
//# sourceMappingURL=codex-runtime-observation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-runtime-observation.d.ts","sourceRoot":"","sources":["../../../src/providers/identity/codex-runtime-observation.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,YACrC,cAAc,EACd,cAAc,CACN,CAAC;AAIX,eAAO,MAAM,wBAAwB,2BAA2B,CAAC;AAKjE,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,wEAAwE;IACxE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,8EAA8E;IAC9E,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B;;;;;OAKG;IACH,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAkLD;;;;;GAKG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,SAAS,OAAO,EAAE,GAC1B,oBAAoB,GAAG,IAAI,CAyD7B;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,GAAG;IACrE,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,IAAI,CAWP"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Captured Codex rollout metadata, sanitized.
|
|
3
|
+
*
|
|
4
|
+
* These fixtures are derived from three real Codex 0.152.1 rollouts produced by
|
|
5
|
+
* one live nested dispatch on the capturing operator's machine, 2026-09-02: a root `exec` session, a depth-1
|
|
6
|
+
* subagent, and a depth-2 subagent. They replaced hand-written fixtures that
|
|
7
|
+
* had been constructed from assumption — those fixtures passed while the parser
|
|
8
|
+
* did not work against any real rollout, which is exactly the failure mode
|
|
9
|
+
* captured evidence prevents.
|
|
10
|
+
*
|
|
11
|
+
* Sanitization is allowlist-based, so a new upstream field cannot silently
|
|
12
|
+
* appear here. Only `session_meta` and `turn_context` payloads are retained,
|
|
13
|
+
* restricted to lineage, identity, and selection keys. Every non-metadata entry
|
|
14
|
+
* keeps its `type` and `ordinal` and carries no payload at all. Dropped
|
|
15
|
+
* outright: `base_instructions`, `git`, `cwd`, `workspace_roots`,
|
|
16
|
+
* `sandbox_policy`, `permission_profile`, and `collaboration_mode` — that is,
|
|
17
|
+
* every instruction, conversation, absolute-path, and repository-identifying
|
|
18
|
+
* field.
|
|
19
|
+
*
|
|
20
|
+
* Structural facts these fixtures preserve, each load-bearing for the parser:
|
|
21
|
+
* - A root declares `thread_source: "user"`, a plain string `source`, and no
|
|
22
|
+
* `parent_thread_id`.
|
|
23
|
+
* - A subagent declares `thread_source: "subagent"`, a tagged
|
|
24
|
+
* `source.subagent.thread_spawn` object with an authoritative `depth`, and a
|
|
25
|
+
* `parent_thread_id` at both the top level and inside `thread_spawn`.
|
|
26
|
+
* - On a subagent, `session_id` is the *root's* id, not its own. Only `id`
|
|
27
|
+
* identifies the session itself.
|
|
28
|
+
* - The depth-1 rollout embeds its parent's history: its own `session_meta` is
|
|
29
|
+
* first at ordinal 0, the parent's `session_meta` follows, and the parent's
|
|
30
|
+
* `turn_context` (`gpt-5.6-sol`) precedes its own (`gpt-5.6-terra`).
|
|
31
|
+
* `subagent_history_start_ordinal` marks where its own records begin.
|
|
32
|
+
* - No real `turn_context` carries a service tier.
|
|
33
|
+
*/
|
|
34
|
+
export declare const ROOT_ROLLOUT: readonly unknown[];
|
|
35
|
+
export declare const DEPTH_1_ROLLOUT: readonly unknown[];
|
|
36
|
+
export declare const DEPTH_2_ROLLOUT: readonly unknown[];
|
|
37
|
+
//# sourceMappingURL=codex-runtime-observation.fixtures.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codex-runtime-observation.fixtures.d.ts","sourceRoot":"","sources":["../../../src/providers/identity/codex-runtime-observation.fixtures.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,eAAO,MAAM,YAAY,EAAE,SAAS,OAAO,EA2K1C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,SAAS,OAAO,EAsO7C,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,SAAS,OAAO,EAsG7C,CAAC"}
|