The problem you're running into is due to a Beginner Student Language restriction: normally, higher-order functions are a syntactic error in the language, because beginners shouldn't know about them yet.
There's a way to opt-out of this. Your procedure-source can be labeled as one of the exceptions to this restriction, by using provide-higher-order-primitive, which is specifically meant to cooperate with BSL.
Here's what your library looks like with it:
#lang racket/base
(require lang/prim
racket/bool
(for-syntax racket/base))
(provide define/save-source)
(provide-higher-order-primitive procedure-name (fn))
(provide-higher-order-primitive procedure-source (fn))
(define *procedure-name-hash* (make-hash))
(define *procedure-source-hash* (make-hash))
(define (save-source! fn name body)
(hash-set! *procedure-name-hash* fn name)
(hash-set! *procedure-source-hash* fn body))
(define (procedure-name fn)
(hash-ref *procedure-name-hash* fn false))
(define (procedure-source fn)
(hash-ref *procedure-source-hash* fn false))
(define-syntax define/save-source
(syntax-rules ()
((_ (name formals ...) body-expressions ...)
(begin
(define name (λ(formals ...) body-expressions ...))
(save-source! name 'name '(λ(formals ...) body-expressions ...))))
((_ name (λ(formals ...) body-expressions ...))
(begin
(define name (λ(formals ...) body-expressions ...))
(save-source! name 'name '(λ(formals ...) body-expressions ...))))
((_ name value)
(define name value))))
BSL programs that use this should be able to use procedure-name and procedure-source fine.