Skip to content

symfonic.agent.cutover.capability_labels

capability_labels

Which capability's switch a refused field is waiting on (cosmetic only).

Split from :mod:~symfonic.agent.cutover.policy when that module passed its line budget again -- the fourth such split, after injections, arguments and TA8.37's memory_admission, and the same one every time: a separate question, read by a different part of a refusal, kept where a reader can check it without the allowlists in the way.

This map cannot admit anything. It only chooses the wording of a refusal that has already been decided. A field absent from it still refuses -- just with the generic sentence, because nobody has yet said which switch would let it through -- so entries are optional and some are omitted deliberately.

capability_for

capability_for(path: str) -> str | None

The switch a field waits on, when one has been named for it.

Every config.domain field shapes the system prompt, so the whole object maps to one capability instead of eleven identical entries. Every config.orchestrator field configures the memory stack, for the same reason and with the same saving (TA8.37).

Source code in src/symfonic/agent/cutover/capability_labels.py
def capability_for(path: str) -> str | None:
    """The switch a field waits on, when one has been named for it.

    Every ``config.domain`` field shapes the system prompt, so the whole
    object maps to one capability instead of eleven identical entries. Every
    ``config.orchestrator`` field configures the memory stack, for the same
    reason and with the same saving (TA8.37).
    """
    if path.startswith("domain."):
        return "prompting"
    if path.startswith("orchestrator."):
        return "memory"
    return _CAPABILITY.get(path)