@@ -372,7 +372,7 @@ export default function DepositPageClient() {
372372 {
373373 id : "source-path-sensitive-scope-warning" ,
374374 label :
375- "Source path hints include sensitive operational terms requiring review." ,
375+ "Forced Inclusion paths include sensitive operational terms requiring review." ,
376376 severity : "warning" as const ,
377377 weight : 0.64 ,
378378 } ,
@@ -1048,6 +1048,38 @@ export default function DepositPageClient() {
10481048 sourcePathHints ,
10491049 ] ) ;
10501050
1051+ // Delete a saved Obfuscations anchor from the activity ledger (hover-trash
1052+ // on the Load-anchor dropdown). Optimistic local removal; server is the
1053+ // fail-closed authority (own row + anchor-source only).
1054+ const handleDeleteObfuscationsAnchor = useCallback ( async ( anchorId : string ) => {
1055+ if ( ! anchorId ) return ;
1056+ const previousRuns = liveRuns ;
1057+ setLiveRuns ( ( current ) => current . filter ( ( run ) => run . id !== anchorId ) ) ;
1058+ setObfuscationsAnchorMessage ( null ) ;
1059+ try {
1060+ const response = await fetch (
1061+ `/api/executions/history/${ encodeURIComponent ( anchorId ) } ` ,
1062+ { method : "DELETE" } ,
1063+ ) ;
1064+ if ( ! response . ok ) {
1065+ const payload = ( await response . json ( ) . catch ( ( ) => null ) ) as {
1066+ error ?: string ;
1067+ } | null ;
1068+ throw new Error (
1069+ payload ?. error || "Unable to delete the Obfuscations anchor." ,
1070+ ) ;
1071+ }
1072+ setObfuscationsAnchorMessage ( "Obfuscations anchor deleted." ) ;
1073+ } catch ( error ) {
1074+ setLiveRuns ( previousRuns ) ;
1075+ setObfuscationsAnchorMessage (
1076+ error instanceof Error
1077+ ? error . message
1078+ : "Unable to delete the Obfuscations anchor." ,
1079+ ) ;
1080+ }
1081+ } , [ liveRuns ] ) ;
1082+
10511083 // Real option synthesis via the AssetPacksSynthesis pipeline (deposit
10521084 // lens). The server route builds the exclusion-filtered source inventory,
10531085 // runs bounded inference, persists the execution row with real
@@ -1722,6 +1754,7 @@ export default function DepositPageClient() {
17221754 ]
17231755 . filter ( Boolean )
17241756 . join ( " " ) ,
1757+ deletable : true ,
17251758 } ) ) }
17261759 value = { null }
17271760 onSelect = { ( key ) => {
@@ -1734,6 +1767,12 @@ export default function DepositPageClient() {
17341767 setSourcePathHints ( anchor . sourcePathHints ) ;
17351768 setProtectedIpExclusions ( anchor . protectedIpExclusions ) ;
17361769 } }
1770+ onDeleteItem = { ( key ) => {
1771+ void handleDeleteObfuscationsAnchor ( key ) ;
1772+ } }
1773+ // One-shot load-in: always shows the placeholder, never
1774+ // a selected value — no check indicator in the list.
1775+ showSelectionIndicator = { false }
17371776 placeholder = "Load anchor..."
17381777 searchPlaceholder = "Search anchors..."
17391778 emptyMessage = "No anchors yet."
@@ -1891,21 +1930,21 @@ export default function DepositPageClient() {
18911930 ) : null }
18921931 </ div >
18931932 { /* File-tree pickers over the selected repository·branch·
1894- commit. Hints and exclusions are MUTUALLY EXCLUSIVE — a
1895- path picked on one side is disabled on the other.
1896- Concept-level withholding belongs to Obfuscations above . */ }
1933+ commit. Forced Inclusion and Forced Exclusions are MUTUALLY
1934+ EXCLUSIVE — a path picked on one side is disabled on the
1935+ other. Concept-level withholding belongs to Obfuscations. */ }
18971936 < div className = "mt-4 grid gap-4 tablet:grid-cols-2" >
18981937 < div className = "block" >
18991938 < span className = "flex items-center gap-2 text-[0.62rem] uppercase tracking-[0.16em] text-neutral-500" >
19001939 < DepositIncludePathsIcon />
1901- < span > Source path hints </ span >
1940+ < span > Forced Inclusion </ span >
19021941 < span onClick = { ( event ) => event . stopPropagation ( ) } >
19031942 < BitcodeInlineExplainer explainer = { DEPOSIT_SECTION_EXPLAINERS . sourcePathHints } triggerAriaLabel = "More info about this field" />
19041943 </ span >
19051944 </ span >
19061945 < div className = "mt-2" >
19071946 < VCSFileTreePicker
1908- aria-label = "Source path hints file tree"
1947+ aria-label = "Forced Inclusion file tree"
19091948 provider = { repositoryContext ?. provider ?? "github" }
19101949 repositoryFullName = {
19111950 repositoryContext ?. selectedRepository ?. fullName ?? null
@@ -1918,21 +1957,21 @@ export default function DepositPageClient() {
19181957 selectedPaths = { sourcePathHints }
19191958 onChange = { setSourcePathHints }
19201959 conflictingPaths = { protectedIpExclusions }
1921- conflictLabel = "Already a protected IP exclusion "
1960+ conflictLabel = "Already a Forced Exclusion "
19221961 />
19231962 </ div >
19241963 </ div >
19251964 < div className = "block" >
19261965 < span className = "flex items-center gap-2 text-[0.62rem] uppercase tracking-[0.16em] text-neutral-500" >
19271966 < DepositExcludePathsIcon />
1928- < span > Protected IP exclusions </ span >
1967+ < span > Forced Exclusions </ span >
19291968 < span onClick = { ( event ) => event . stopPropagation ( ) } >
19301969 < BitcodeInlineExplainer explainer = { DEPOSIT_SECTION_EXPLAINERS . protectedIpExclusions } triggerAriaLabel = "More info about this field" />
19311970 </ span >
19321971 </ span >
19331972 < div className = "mt-2" >
19341973 < VCSFileTreePicker
1935- aria-label = "Protected IP exclusions file tree"
1974+ aria-label = "Forced Exclusions file tree"
19361975 provider = { repositoryContext ?. provider ?? "github" }
19371976 repositoryFullName = {
19381977 repositoryContext ?. selectedRepository ?. fullName ?? null
@@ -1945,14 +1984,14 @@ export default function DepositPageClient() {
19451984 selectedPaths = { protectedIpExclusions }
19461985 onChange = { setProtectedIpExclusions }
19471986 conflictingPaths = { sourcePathHints }
1948- conflictLabel = "Already a source path hint "
1987+ conflictLabel = "Already a Forced Inclusion "
19491988 />
19501989 </ div >
19511990 < span className = "mt-1 block text-xs leading-5 text-neutral-500" >
1952- Excluded paths never enter AssetPack knowledge synthesis:
1953- they are removed from the source inventory before
1954- measurement, and candidates that touch them are dropped
1955- fail-closed. Concept-level withholding belongs in
1991+ Forced Exclusions never enter AssetPack knowledge
1992+ synthesis: they are removed from the source inventory
1993+ before measurement, and candidates that touch them are
1994+ dropped fail-closed. Concept-level withholding belongs in
19561995 Obfuscations above.
19571996 </ span >
19581997 </ div >
@@ -1985,7 +2024,7 @@ export default function DepositPageClient() {
19852024 >
19862025 { synthesisStatus === "running"
19872026 ? "Synthesizing with AssetPacksSynthesis…"
1988- : "Synthesize options " }
2027+ : "Synthesize AssetPack Options " }
19892028 </ button >
19902029 ) }
19912030 </ section >
@@ -2001,10 +2040,10 @@ export default function DepositPageClient() {
20012040 < div className = "flex flex-wrap items-start justify-between gap-3" >
20022041 < div >
20032042 < p className = "text-[0.68rem] uppercase tracking-[0.22em] text-emerald-200/80" >
2004- Options
2043+ Source-Safe Proposals
20052044 </ p >
20062045 < h2 className = "mt-2 flex items-center gap-2 text-lg font-semibold text-white" >
2007- < span > Source-safe AssetPack proposals </ span >
2046+ < span > AssetPack Options </ span >
20082047 < BitcodeInlineExplainer explainer = { DEPOSIT_SECTION_EXPLAINERS . options } />
20092048 </ h2 >
20102049 </ div >
0 commit comments