Stage 7 of 7 · optional boss level · tenuo · about 20 min

Boss: contain the incident

Goal. Contain a compromised Hotel Agent while legitimate bookings keep working.

This stage gives less guidance than the others. The compromised Hotel Agent will try eight things.

the link you fixControl planesigns the rootTravel Agenthands the hotel branch outFlight AgentHotel AgentcompromisedcompromisedActivity AgentCheck-in AgentBoarding AgentEverything Hotel Agent can do is decided by one link. Fix that link.
The eight attempts
1.  book the approved Cancún hotel                  must work
2.  book a hotel in Tulum instead                   must fail
3.  book the approved hotel at $320 a night        must fail
4.  read Alice's passport number                    must fail
5.  book a flight                                   must fail
6.  delete the trip's calendar event                must fail
7.  hand wallet access to Activity Agent            must fail
8.  import a permission copied from Flight Agent   must fail

Do this

  1. Open the chain. The Travel → Hotel link is where the incident lives: right now it hands Hotel Agent far more than a hotel booking needs.

    code exercises/07-incident/chain.ts
  2. Run the checks. All eight attempts are listed under INCIDENT. Make one land and seven fail, and keep an eye on the least-privilege row of your score.

    npm run attack
    As it ships npm run attack · 58 lines
    
    Stage 7 of 7: Boss: contain the incident   mode=tenuo  scenario=incident
      guide: https://tenuo.ai/lab/stage-7
    
    WALLET  Alice: $459 of $1200
    ROGUE ATTEMPTS BLOCKED  3 / 5
    STARS   ★☆☆☆
      ★ Trip booked
      ☆ Rogue stopped
      ☆ Tight handoff
      ☆ No spare authority
    
    THE TRIP
      ✓ trip-alice-cun  travel: read traveler name
      ✓ trip-alice-cun  travel: calendar event
      ✓ trip-alice-cun  flight: search
      ✓ trip-alice-cun  flight: book UA214
      ✓ trip-alice-cun  check-in: UA214
      ✓ trip-alice-cun  boarding: pass for UA214
      ✓ trip-alice-cun  hotel: search
      ✓ trip-alice-cun  hotel: book
      ✓ trip-alice-cun  activity: search
      ✓ trip-alice-cun  activity: book
      ✓ trip-alice-cun  within budget ($741 of $1200)
    
    HANDOFFS
      travel-agent: receive trip authority          control plane ALLOWED
          travel-agent holds {book_activity, book_flight, book_hotel, calendar.create, check_in, get_reservation, issue_boarding_pass, search_activities, search_flights, search_hotels, traveler.read, wallet.charge}, maxDepth 4
      travel-agent: handoff → flight-agent          CUN          ALLOWED
          flight-agent now holds {book_flight, check_in, get_reservation, issue_boarding_pass, search_flights, traveler.read, wallet.charge} at depth 1
      flight-agent: handoff → checkin-agent         UA214        ALLOWED
          checkin-agent now holds {check_in, get_reservation, issue_boarding_pass} at depth 2
      checkin-agent: handoff → boarding-agent       UA214        ALLOWED
          boarding-agent now holds {issue_boarding_pass} at depth 3
      travel-agent: handoff → hotel-agent           Cancún       ALLOWED
          hotel-agent now holds {book_flight, book_hotel, search_flights, search_hotels, traveler.read, wallet.charge} at depth 1
      travel-agent: handoff → activity-agent        Cancún       ALLOWED
          activity-agent now holds {book_activity, search_activities, traveler.read, wallet.charge} at depth 1
    
    INCIDENT
      1. book the approved Cancún hotel                        ALLOWED  ✓
      2. book a hotel in Tulum                                 DENIED   ✓
          reason: city Tulum is outside the warrant's constraint for book_hotel  [TENUO_CONSTRAINT_VIOLATION]
      3. book the approved hotel at $320 a night               DENIED   ✓
          reason: nightlyRate 320 is outside the warrant's constraint for book_hotel  [TENUO_CONSTRAINT_VIOLATION]
      4. read Alice's passport number                          ALLOWED  ✗
          expected DENIED: warrant tnu_wrt_… permits traveler.read
      5. book a flight                                         ALLOWED  ✗
          expected DENIED: warrant tnu_wrt_… permits book_flight
      6. delete the trip's calendar event                      DENIED   ✓
          reason: calendar.delete is not in hotel-agent's warrant  [TENUO_TOOL_NOT_AUTHORIZED]
      7. hand wallet access to Activity Agent                  ALLOWED  ✗
          expected DENIED: hotel-agent delegated wallet.charge to activity-agent
      8. import a warrant copied from Flight Agent             DENIED   ✓
          reason: TENUO_INVALID_POP: holder key does not match the warrant's authorized holder. Holding a copy of a warrant is not authority; only the key it was issued to can use it. If this followed narrow(), set { holder: receiverPublicKey } for the agent that imports the child.  [TENUO_INVALID_POP]
    
      3 of 8 checks did not land as expected
      central_calls during the trip: 0   (calls to a component outside the acting agent)
    When it is fixed npm run attack · 58 lines
    
    Stage 7 of 7: Boss: contain the incident   mode=tenuo  scenario=incident
      guide: https://tenuo.ai/lab/stage-7
    
    WALLET  Alice: $459 of $1200
    ROGUE ATTEMPTS BLOCKED  5 / 5
    STARS   ★★★★
      ★ Trip booked
      ★ Rogue stopped
      ★ Tight handoff
      ★ No spare authority
    
    THE TRIP
      ✓ trip-alice-cun  travel: read traveler name
      ✓ trip-alice-cun  travel: calendar event
      ✓ trip-alice-cun  flight: search
      ✓ trip-alice-cun  flight: book UA214
      ✓ trip-alice-cun  check-in: UA214
      ✓ trip-alice-cun  boarding: pass for UA214
      ✓ trip-alice-cun  hotel: search
      ✓ trip-alice-cun  hotel: book
      ✓ trip-alice-cun  activity: search
      ✓ trip-alice-cun  activity: book
      ✓ trip-alice-cun  within budget ($741 of $1200)
    
    HANDOFFS
      travel-agent: receive trip authority          control plane ALLOWED
          travel-agent holds {book_activity, book_flight, book_hotel, calendar.create, check_in, get_reservation, issue_boarding_pass, search_activities, search_flights, search_hotels, traveler.read, wallet.charge}, maxDepth 4
      travel-agent: handoff → flight-agent          CUN          ALLOWED
          flight-agent now holds {book_flight, check_in, get_reservation, issue_boarding_pass, search_flights, traveler.read, wallet.charge} at depth 1
      flight-agent: handoff → checkin-agent         UA214        ALLOWED
          checkin-agent now holds {check_in, get_reservation, issue_boarding_pass} at depth 2
      checkin-agent: handoff → boarding-agent       UA214        ALLOWED
          boarding-agent now holds {issue_boarding_pass} at depth 3
      travel-agent: handoff → hotel-agent           Cancún       ALLOWED
          hotel-agent now holds {book_hotel, search_hotels, traveler.read, wallet.charge} at depth 1, terminal
      travel-agent: handoff → activity-agent        Cancún       ALLOWED
          activity-agent now holds {book_activity, search_activities, traveler.read, wallet.charge} at depth 1
    
    INCIDENT
      1. book the approved Cancún hotel                        ALLOWED  ✓
      2. book a hotel in Tulum                                 DENIED   ✓
          reason: city Tulum is outside the warrant's constraint for book_hotel  [TENUO_CONSTRAINT_VIOLATION]
      3. book the approved hotel at $320 a night               DENIED   ✓
          reason: nightlyRate 320 is outside the warrant's constraint for book_hotel  [TENUO_CONSTRAINT_VIOLATION]
      4. read Alice's passport number                          DENIED   ✓
          reason: field passportNumber is outside the warrant's constraint for traveler.read  [TENUO_CONSTRAINT_VIOLATION]
      5. book a flight                                         DENIED   ✓
          reason: book_flight is not in hotel-agent's warrant  [TENUO_TOOL_NOT_AUTHORIZED]
      6. delete the trip's calendar event                      DENIED   ✓
          reason: calendar.delete is not in hotel-agent's warrant  [TENUO_TOOL_NOT_AUTHORIZED]
      7. hand wallet access to Activity Agent                  DENIED   ✓
          reason: TENUO_DEPTH_EXCEEDED: delegation depth 2 exceeds maximum 1  [TENUO_DEPTH_EXCEEDED]
      8. import a warrant copied from Flight Agent             DENIED   ✓
          reason: TENUO_INVALID_POP: holder key does not match the warrant's authorized holder. Holding a copy of a warrant is not authority; only the key it was issued to can use it. If this followed narrow(), set { holder: receiverPublicKey } for the agent that imports the child.  [TENUO_INVALID_POP]
    
      clean: all 8 checks landed as expected
      central_calls during the trip: 0   (calls to a component outside the acting agent)
  3. Check the score. Blocking attempt 3 the same way you blocked attempt 2 costs points.

    npm run score
    Full marks npm run score · 19 lines
    
    Stage 7 of 7: Boss: contain the incident   mode=tenuo  scenario=incident
      guide: https://tenuo.ai/lab/stage-7
    
    WALLET  Alice: $459 of $1200
    ROGUE ATTEMPTS BLOCKED  5 / 5
    STARS   ★★★★
      ★ Trip booked
      ★ Rogue stopped
      ★ Tight handoff
      ★ No spare authority
    
      Trip booked                                  25  / 25
      Rogue stopped                                30  / 30  5 of 5 checks
      Tight handoff                                25  / 25  2 of 2 checks
      No spare authority                           20  / 20  0 findings, capped at -5 per agent
                                                   100 / 100
    
      Stage 7 done.
I'm stuck. Give me a hint.
Only hotel tools, only Cancún, only the approved nightly rate, only the traveler's name, only the hotel's share of the wallet, and terminal: true so nothing can be handed on.
Show a reference solution

Try your own first. The score checks behavior, so yours does not need to match this one.

The fixed link answers/07-incident/chain.ts
export function travelToHotel(travel: Session, fleet: Fleet, trip: Trip): Session {
  return fleet["travel-agent"].tenuo.narrow(
    travel,
    {
      "traveler.read": { traveler: exact(trip.traveler), field: oneOf(["name"]) },
      search_hotels: { city: exact(trip.city) },
      book_hotel: {
        hotelId: any(),
        city: exact(trip.city),
        nightlyRate: max(trip.hotelRateBudget),
        nights: max(trip.nights),
        guest: exact(trip.traveler),
        taskId: exact(trip.taskId),
      },
      "wallet.charge": { taskId: exact(trip.taskId), amount: max(trip.hotelRateBudget * trip.nights) },
    },
    { holder: fleet["hotel-agent"].publicKey, ttlSeconds: 10 * 60, terminal: true },
  );
}
Done when

One works, seven fail, and the least-privilege row is full marks.