docs: update OpenWiki

This commit is contained in:
AkinoKaede authored and 秋野かえで committed 2026-10-20 10:55:33 +08:00
1 parent f117777ef8
commit fdd419701d
19 files changed
+355 -246

No files matched your search

@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:83b518f3d06d6183be6cb6a714ca0cb0042666de8d7510a874ef16d382a5e71d",
"pageVersion": "sha256:f5f9c4a9a57e7bbbc3940fe9327a9cd727922542523d58b86aca97d93d260cdd",
"claims": [
{
"id": "claim_72f9329a158e418cbf0fd6394f82815e",
@@ -428,31 +428,39 @@
},
{
"id": "claim_ece93976c37a44359339e07fb010a4f4",
"statement": "AgentToolPresentation decodes result JSON for injected presenters or generic formatting, passing failure state and suppressing duplicate denial reasons; both apps register localized SSH result presenters preserving tool-owned layout and approval policy, with pending detail only for result-less SSH cards. MCP retains JSON without a presenter but accepts explicitly injected trusted presenters; remote metadata cannot select local code. Failed knowledge results must not render success detail.",
"statement": "AgentToolPresentation decodes result JSON for injected presenters or generic formatting, passing failure state and suppressing duplicate denial reasons; both apps register localized SSH result presenters preserving tool-owned layout and approval policy, with pending detail only for result-less SSH cards. MCP descriptors cannot select local executable presenters through remote metadata, but their empty default profile permits generic structured JSON rendering without a presenter (the test renders value 42 as a Value field), and explicitly injected trusted presenters and layouts are accepted. Failed knowledge results must not render success detail.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift",
"version": "repo-file-v1:sha256:7e73ee136dbf26955f003be86adb8b83dee3914c18012efa5bb5e2a45db83351"
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift#L296-L374",
"version": "repo-lines-v1:sha256:d9fc2661bf316fbf5dd7515c8e66199af202b7bcf1dee9c0dd25b58e5fae65db:eyJzZWxlY3RlZExpbmVDb3VudCI6NzksImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM2NDczYmRlOGY2OTkyZGFkOGY5YzhmYTczN2QxOTAxZGM1ZGM0ODUxYTVkZjE2OWNmYzY1MWZiMmY4OWY1NTEiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjVlOGQ2NGFjYmIyYjdhOTIyYWM5Yjg4MjdkMWZjYmNjZjc4ODE3MThhODliNjJmNDQ0ZDhhZGM3NGQ1MzJhMzAiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjVmZjAwNmM3NTU4MzlhOTdiMDczYmM5NTBlNTVjMjJiMTM4Y2U0MTAxZWQ0N2I2MDU5OTAyOTRhNmQ0ZDg1NWUifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/SSHExecToolPresentation.swift",
"version": "repo-file-v1:sha256:d521c370d8f3641b5269fc4a4b37bce16ec93cec854bc9f8798e741809035c12"
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift#L33-L48",
"version": "repo-lines-v1:sha256:aea0415db871ab89131bd88948c4f5141188a27f1960105e951110df0d1bd845:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImI2MjgyYjY2ZGE5YTg1NGJlZjVlZWNjNjczMmFmNGFhNjBhMGYwZDNiY2NlYzAxYmE3MzVhZGI5MjkwMmEzN2YiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM5MjQzNjA5Zjc2YTNkOGFmYmZiZGQ3OWYwMDRmNmJlNzdmMjI2NGJiYmI5OTBhMmI0N2M4NzUyYzc3ZmUxNTIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjYyYjA3NDk2Yzk2ODY5N2E1YWRiNWRjNWZmZjlmYWYzNWRlZTU3NzUyY2FjZGZkOTZiNWNjZjdiMzE5ZGRiNWEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
},
{
"resource": "repo://TFI/App/MobileAppDependencies.swift",
"version": "repo-file-v1:sha256:f04bcb7fb5a9b4cdecf96182e7512cae9ab1dcf90d76b604ee59f2e77cc03268"
"resource": "repo://Frameworks/TermindPresentation/SSHExecToolPresentation.swift#L12-L47",
"version": "repo-lines-v1:sha256:f53c0792faf05444d731eac4eae25e18c91d27ecbfda0a7c0f71175768f91110:eyJzZWxlY3RlZExpbmVDb3VudCI6MzYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjE4NzRiNmZjMTM1ZGUzNDVlNWRhMjU0OWM5YmQ4N2ExMGY4MTRhYWVkNTExODllN2QzNGVjOGZkODIwZGUxZDMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6ImY5YjE5ODJlOGRkNzQ4MTE4MTQ2YjM5YTJkMDA2MmY0MDgxZTM0Nzc5Yjg2NzVjMjM0YzRmYjEyNGRjMzkzOTAiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjA1NDAwNTRjMjBhNmMyOWJiNmNiY2JhMDM2ZjNkYmE0Y2Q4ZmYxMDFlNzUxNjdmMzhhZTg3OGY2ZGE3MmJlOWQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjAyZGIzYzIyZGJjZjQ5Njg4MDk4NmYzZWUzODQ2ZTk2ZDkwZTkwOTAyYTdkMjA0MzY2NjZhODVhYzA1MWEzYmIifQ"
},
{
"resource": "repo://TFM/App/AppDependencies.swift",
"version": "repo-file-v1:sha256:4f41b87923515af027f96232867e44d36da599633c78e82564f1f872b295224f"
"resource": "repo://Frameworks/TermindRemoteInfrastructure/Agent/TermindAgentTools.swift#L63-L74",
"version": "repo-lines-v1:sha256:50401944ea17a305733c6cb3190318d7fcb13d56de8a326acfcdcc7261cdb8d3:eyJzZWxlY3RlZExpbmVDb3VudCI6MTIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImYyYTU2YjYxYzU3Mzg4MjMxYTM4ZTNkYzJmNjlkMmNhMjRhODQ3MmNlOTUyMzIwOTgwYTEyZWU2YmVlMmVlZTMiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjBhZTczN2RiZTA2MWMzMmY2NzYwYzIwNjE2ODMyYmVhYTA0MjU5YzkyODExMjhhM2M1NjhkMmNjMmIzNDRlYWQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImVjNmNiNzk1N2Y1ODdiZjMyMWE1NDgxOTFlMTEzYjlkZDBjYzdhM2M3ODU1NjQ1ZjQxZGExMDg4MmVlYmFlYjAifQ"
},
{
"resource": "repo://TFMTests/AgentKnowledgeToolPresentationTests.swift",
"version": "repo-file-v1:sha256:dbb44bb5fae9f0332c402febdb4ba2e6327bc7b8819eefa4bce3bcb138e90e1e"
"resource": "repo://TFI/App/MobileAppDependencies.swift#L10-L17",
"version": "repo-lines-v1:sha256:623a2e002811c749f0e2e3d9253a4706dc0add8c2f6e178afd9eb77cfc713d9b:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYTEwMTIzZDk3OGIzN2M1NWRkYTAyZGJmYmYyMjBjNjBhMzNkNDhhM2QzMjJjYTk1MjdkZTc5YzNmODFlNDFmMSIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiMmE0ZDY1ODhmOWI3YWQwODA5MzgyODExMDk1NTQ3ZTJjZDE4OGEzYTM0ZDMzM2E0OGQ4YmM5NzgxZDY0NTM5NyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMjk5ZDlhYzA3OTMzMWRlMTcwYWNjYTE1YjNiMWMwYzI5ZjE1OGRkYmRiMDU1NTRkOGM5NmU0MzM1OTE5M2M3ZSJ9"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift",
"version": "repo-file-v1:sha256:2f2610b7c2271c5954f502680d5eb22b332bf8a2bdeb186b0833d12381080400"
"resource": "repo://TFM/App/AppDependencies.swift#L20-L27",
"version": "repo-lines-v1:sha256:d7f4bcbc7406554c1915946793e839ed5922f9d2770b3d1640a2b69a15e6e3af:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYjFjMmVhZTY2ZTVlZmJlYTc4NDg4YzZjOTcxZjA1ZjA2NGNkY2Q2ZDljNWVjYmU2YTZmMmVjZGIyNjZkZjdlNCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNmM0ZjYxZDRhYTM3OTExNDhhNTI0ZmY3MDZhYTlhODYyNDAwNmQ0Y2ExMjNlYzc1ZThiNDM5NGViZmRiN2E5ZSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiOGQ1ZDNmZWNjMzhiODZlYzZjNWUzZTYwYjcwZTE4ZTE3NjAxMmY0OTI5YjdkYWQ4YmE2Zjk5NDgxMDI2YzEyZCJ9"
},
{
"resource": "repo://TFMTests/AgentKnowledgeToolPresentationTests.swift#L103-L114",
"version": "repo-lines-v1:sha256:3944f535013814fd5c5a68303b4177cf572d9af5b09cd162338fa0d222061c58:eyJzZWxlY3RlZExpbmVDb3VudCI6MTIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjE4NGJlNzI0YjgwNWEyYjZlYjIyMjI0NWExNTZmYmQ5NjBmNTZjZTllZjEzMzJjYTBhM2I5ZTQ2ZjBmNWI1OTgiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6ImVmNjA3ODI4ZDQxZDU5YjhjM2Y0YmZmOWQ0ZWQyZDRkODYyMzRlOGZmOGE4M2U5OTQ4OGYyMjhjNWQzMzMzZWEiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjllOWRiNGVhNTg4NTRhODRhYmY1YzY2ZDM5MGFmMDEyZDhiZDMwMDRmZjA2MWE3NWUxOTk5YmRiMDkyZTI0ZjAiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjM1ZWE0NmNhMjI1Mjk4MzllMTVjOTk5YjQ2NmJkYTkxN2Q5NTAzMzMyYzcwMmZiYTc4ZWFlMzZhMzM5ODU2ZDQifQ"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L63-L86",
"version": "repo-lines-v1:sha256:a06d7ae6b30a477119f50f28f9cdc65063bfe4ed037fcfbf7a07f1802f911153:eyJzZWxlY3RlZExpbmVDb3VudCI6MjQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjA5ZGFiMjJkYzFkOTE1MGEwN2NhYWMzZTI4YTNjMjEzM2QzZWZhMjQ4ZmMwOGY3ZjJkZTNkNTQ3ODZjMDgzZWEifQ"
}
]
},
@@ -1210,25 +1218,25 @@
},
{
"id": "claim_7ae40d8d6694416fa4396d7ba7d9233e",
"statement": "AgentToolPresentation renders descriptor metadata and lifecycle state through injected profiles and vocabulary without rewriting original execution, approval, persistence or replay data. TermindToolPresentationProfiles composes ordinary tool semantics by registered presenter ID, refuses unknown-ID name fallback, and enforces local pane/chat privacy independently of presenter availability.",
"statement": "AgentToolPresentation renders descriptor metadata and lifecycle state through injected profiles and vocabulary without rewriting original execution, approval, persistence or replay data. TermindToolPresentationProfiles returns an empty profile for MCP before local lookup; otherwise ordinary semantics follow registered presenter IDs, with missing or unknown IDs using defaults rather than name fallback. Local pane/chat name-based privacy overrides presenter-ID lookup independently of presenter availability.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift",
"version": "repo-file-v1:sha256:7e73ee136dbf26955f003be86adb8b83dee3914c18012efa5bb5e2a45db83351"
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift#L5-L20",
"version": "repo-lines-v1:sha256:2436a27e43692435d2ad3ba524dfecdf72b1f6b038b87419a54bcc0aae0675e1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA4N2M2MmQ1ZDM3N2M2MzQyZjM5ZjVjMDgxOWY5Y2Q0NWZiODFmNTEyZmUxYzk3NGYxNjJlMmRkOGRmNTE3M2UiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImM0NmY4Y2RkMDA0NDk4MWZkNzI0N2EwYzg5MzE2ODM0ZDNlZGFjOWU1MTAwNThkNGMwNGNhM2RkODczYzFhYTYiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjUyOGU4Mzk3ZDg4Y2QzOTJmNzc3YmU4ZjUzOTY4YmJjZTNmYmI5MTUzZmZlMWFkM2I5ZWVmMjk2YmU1NzJkNzcifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift",
"version": "repo-file-v1:sha256:c9d67b4b871d3bbd2c7dc81ca1f5382f812f6bb90607fd068a9e3edd3ccfbd0a"
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift#L25-L38",
"version": "repo-lines-v1:sha256:6a657a430947e742759792a69e15ae5a86af0c33f248e517e7c7a2aa9efb7df7:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3MjE3OGJiOTBhNjc4MmVjNWM3NGIwZDMzMDhjMzc5YzUxYjUwYTgwYmUwMzc1Y2VmNWYzYjFlNDA2Y2VjZWIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk3NDFmMzk5NTFhOGRhNzAzMzFlMDJjZmRkMzQwZjAxYzZiNTVkZThhNmE3Yjk2OTRkNTg0MDQ1ZDExYjY0NjQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift",
"version": "repo-file-v1:sha256:2f2610b7c2271c5954f502680d5eb22b332bf8a2bdeb186b0833d12381080400"
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L88-L104",
"version": "repo-lines-v1:sha256:4f1f9049cbfddfc8e49d401057baec1355a404f907344995208e1804dc9d8ba1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTcsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjY4MjI3MTYyOGYwMjg3NTRmYjRlMjMwMzZhYjMxZjhhOTI2MzNkOWI0NDlhYTkzMmJkNjg2MWVkOTZiY2IyMjEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
}
]
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:cdeb6b232f8ffeb719f49412418183c6ed537f7fd160ee92a36778fe0057e406",
"pageVersion": "sha256:e22f50b68e7ce28efe8e4bd2a58cd620e5656fbdcb7b466e858f7a2da17a535b",
"claims": [
{
"id": "claim_085ce722f39f48eea75366ec3b3f7554",
@@ -638,61 +638,65 @@
},
{
"id": "claim_7cc9dd2b1ac745c7bed455c88b26b175",
"statement": "AgentToolPresentation is a generic renderer driven by injected profiles and vocabulary; TermindToolPresentationProfiles composes knowledge, SSH, pane and chat policy for summaries, phases, details, approval projection and truncation without modifying execution or replay payloads. Unknown or absent presenter IDs do not recover SSH semantics from tool names.",
"statement": "AgentToolPresentation is a generic renderer driven by injected profiles and vocabulary without modifying execution, approval or replay payloads. TermindToolPresentationProfiles composes knowledge, SSH, pane and chat policy, selecting an empty profile for MCP first, local pane/chat privacy by name next, and otherwise a profile by explicit presenter ID or an empty profile. Unknown or absent IDs do not recover SSH semantics by tool name, although generic descriptor metadata still drives rendering.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift#L5-L20",
"version": "repo-lines-v1:sha256:2436a27e43692435d2ad3ba524dfecdf72b1f6b038b87419a54bcc0aae0675e1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA4N2M2MmQ1ZDM3N2M2MzQyZjM5ZjVjMDgxOWY5Y2Q0NWZiODFmNTEyZmUxYzk3NGYxNjJlMmRkOGRmNTE3M2UiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImM0NmY4Y2RkMDA0NDk4MWZkNzI0N2EwYzg5MzE2ODM0ZDNlZGFjOWU1MTAwNThkNGMwNGNhM2RkODczYzFhYTYiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjUyOGU4Mzk3ZDg4Y2QzOTJmNzc3YmU4ZjUzOTY4YmJjZTNmYmI5MTUzZmZlMWFkM2I5ZWVmMjk2YmU1NzJkNzcifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift",
"version": "repo-file-v1:sha256:1937a7d0ca1dc86e3777b9457193d92c761f79b59ce221e28377ae89fe3d6eed"
},
{
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift",
"version": "repo-file-v1:sha256:c9d67b4b871d3bbd2c7dc81ca1f5382f812f6bb90607fd068a9e3edd3ccfbd0a"
"version": "repo-file-v1:sha256:fd9e4be4c236ac64d433a68887986d4decd57b9ad1e8f5d34579da00ae6de729"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift",
"version": "repo-file-v1:sha256:2f2610b7c2271c5954f502680d5eb22b332bf8a2bdeb186b0833d12381080400"
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L88-L104",
"version": "repo-lines-v1:sha256:4f1f9049cbfddfc8e49d401057baec1355a404f907344995208e1804dc9d8ba1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTcsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjY4MjI3MTYyOGYwMjg3NTRmYjRlMjMwMzZhYjMxZjhhOTI2MzNkOWI0NDlhYTkzMmJkNjg2MWVkOTZiY2IyMjEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
}
]
},
{
"id": "claim_b3190cf08737403595ffffc081bd83a8",
"statement": "Presentation profiles distinguish hidden detail from default fallback to prevent private content reaching raw rendering; local pane/chat privacy policy applies independently of presenter availability. MCP profiles preserve unprojected JSON and remote metadata cannot select local presenters, although explicitly supplied trusted presenters can project MCP cards.",
"statement": "Profile detail distinguishes hidden output from default fallback, stopping hidden content before generic JSON/error rendering; local pane/chat privacy applies independently of presenter availability or executable registration. Trusted app composition gates descriptor presenter lookup through TermindAgentTools, which rejects MCP metadata selecting local code. MCP receives an empty profile, not raw-JSON preservation: default decoded results use generic items without a presenter, or an explicitly caller-supplied presenter and its layout; non-JSON results use generic text/error rendering.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentPaneToolPresentation.swift",
"version": "repo-file-v1:sha256:30a43572cc3dae6da49fc1fecdad8111d7c81dd32667003d7c4cbddc50fe0cf7"
"resource": "repo://Frameworks/TermindPresentation/AgentPaneToolPresentation.swift#L33-L76",
"version": "repo-lines-v1:sha256:f8cfac3764b34ff050a6a10304f67eb970bd6d5027a93218ab90298c54026613:eyJzZWxlY3RlZExpbmVDb3VudCI6NDQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjdjNDQ4ZTQyZjc0NWI3ZThjOTZmNjg4YzYyNzE2NzM1MjVlYmM2OTZlNjMyY2NhYTc1OTNkMzQ4Mjk3ZjRmYzgiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRiYzg2Y2EzMzVlNzIyOTY5NzNmZmI2NTJjNTkzMzljZjIwMTQxNTcyNTA1NmFiNTk1MzQ2MWU2YjI0ODAwNWIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImJhOTIzZDYzZDViZTc0YmJkZmIxN2Q2ODJmYTlkZTJkNjY1M2VkYjcwODQ5OGE3YmIwMDBiYTc2ZWM1ODY1ZmEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjU0YjEzMTRjNGU0MjQzMDUxNzE0YzYxZGMxMmVkNTdlMzU2OTc2MzAxMDJmMjVkMDIxOGI3NzhiNWUyMDBlZDUifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift#L25-L45",
"version": "repo-lines-v1:sha256:9ee022bf3dd36b795d355f73c002555441b93800cf7ec04d6566e511f79dd410:eyJzZWxlY3RlZExpbmVDb3VudCI6MjEsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3M2UzZTFkOGNiZjI0MmNjMmU2NTlmNmYzYWM4ZWZkZjQ0MGI5OWM2YjZkMWM4YjdjNTgxMDgyMmE1NGRmNGYiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM4NDRiZmU1ZDUxOGUxYmFjZmE3MjViMzM4ZjRlOGU0M2JjZWI3MTdhMDFkOWViYjg2OTFjNzgwODlmMzI5OTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk5OWJkZWZlZWFjYTYzNDBlMDI5MGRjODZlODg5Yzg5ZDVlMTg5YWE1YmE0NGI1ODViM2I3MDczNGY0YTYyZDgiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImQ5ZDhlZDQxYTc5ZDVkYzMwYTM4OGZhMDk0NTYzM2QxYTY2Y2FhYjkxYmViYzNiYTZkNjNhNDYzMmRmNmU4MWIifQ"
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift#L312-L374",
"version": "repo-lines-v1:sha256:ee92ed4bb504a877a4ba0dc6dfa4fd01ae4f112fc0a10c46661facec3a029241:eyJzZWxlY3RlZExpbmVDb3VudCI6NjMsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImIzZTEyMGRlODYzNWZlY2VkNWMxYTA4YTc2YzAzODhhNjAyYzRlNWViZDYyNWU5NGVmYTNjZjk4M2QwODRkM2QiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjY4YWNlOWI3NWYyZWQ5ZTRiMDk4NTZlNGJjYjFhMDJiMzVjNzY1MzRjNzhiZjM0MjZlYjllYWQxNWM2YmUyYTAiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjVmZjAwNmM3NTU4MzlhOTdiMDczYmM5NTBlNTVjMjJiMTM4Y2U0MTAxZWQ0N2I2MDU5OTAyOTRhNmQ0ZDg1NWUifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift#L25-L40",
"version": "repo-lines-v1:sha256:1a788f9f8138173d1127343cba4c6854bfa367176d9b46c6c49b65a1b5c6c9a9:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3MjE3OGJiOTBhNjc4MmVjNWM3NGIwZDMzMDhjMzc5YzUxYjUwYTgwYmUwMzc1Y2VmNWYzYjFlNDA2Y2VjZWIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk3NDFmMzk5NTFhOGRhNzAzMzFlMDJjZmRkMzQwZjAxYzZiNTVkZThhNmE3Yjk2OTRkNTg0MDQ1ZDExYjY0NjQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift#L25-L48",
"version": "repo-lines-v1:sha256:c74bb326fccf6a63bfdeafa77d1c84217c212d43c2ab8944501f74fc91c6659a:eyJzZWxlY3RlZExpbmVDb3VudCI6MjQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3M2UzZTFkOGNiZjI0MmNjMmU2NTlmNmYzYWM4ZWZkZjQ0MGI5OWM2YjZkMWM4YjdjNTgxMDgyMmE1NGRmNGYiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM5MjQzNjA5Zjc2YTNkOGFmYmZiZGQ3OWYwMDRmNmJlNzdmMjI2NGJiYmI5OTBhMmI0N2M4NzUyYzc3ZmUxNTIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk5OWJkZWZlZWFjYTYzNDBlMDI5MGRjODZlODg5Yzg5ZDVlMTg5YWE1YmE0NGI1ODViM2I3MDczNGY0YTYyZDgiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L63-L104",
"version": "repo-lines-v1:sha256:2e683a7cfc6d1a0324b452c5e5cc75140e46613ecc04f2f42bf371828fbd836a:eyJzZWxlY3RlZExpbmVDb3VudCI6NDIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift#L25-L38",
"version": "repo-lines-v1:sha256:6a657a430947e742759792a69e15ae5a86af0c33f248e517e7c7a2aa9efb7df7:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3MjE3OGJiOTBhNjc4MmVjNWM3NGIwZDMzMDhjMzc5YzUxYjUwYTgwYmUwMzc1Y2VmNWYzYjFlNDA2Y2VjZWIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk3NDFmMzk5NTFhOGRhNzAzMzFlMDJjZmRkMzQwZjAxYzZiNTVkZThhNmE3Yjk2OTRkNTg0MDQ1ZDExYjY0NjQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
},
{
"resource": "repo://Frameworks/TermindRemoteInfrastructure/Agent/TermindAgentTools.swift#L60-L74",
"version": "repo-lines-v1:sha256:cc6484a13635f00edc8c77582bbf0fd425ace1d2d566a90118292db8ec786eec:eyJzZWxlY3RlZExpbmVDb3VudCI6MTUsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjkyZDMzMDFlNWE3MGRjYTk1NjFjNjY4NWE4NjdhNDAwNWFkYjM2ZTg3Nzk4ZjkxYWY1ODY2NTRmNTFkYTAwZjYiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjVmZDhkYmMxYWQ0N2NmOTVhNGRkMGUzZThjNDg1MGFmZjkwMTRiMmE5ZDZlYzJiYmQ0Njg2ZmEwYTk2NGMxMWEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImVjNmNiNzk1N2Y1ODdiZjMyMWE1NDgxOTFlMTEzYjlkZDBjYzdhM2M3ODU1NjQ1ZjQxZGExMDg4MmVlYmFlYjAifQ"
},
{
"resource": "repo://TFM/App/AppDependencies.swift#L20-L27",
"version": "repo-lines-v1:sha256:d7f4bcbc7406554c1915946793e839ed5922f9d2770b3d1640a2b69a15e6e3af:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiYjFjMmVhZTY2ZTVlZmJlYTc4NDg4YzZjOTcxZjA1ZjA2NGNkY2Q2ZDljNWVjYmU2YTZmMmVjZGIyNjZkZjdlNCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiNDg5M2Y0MGUzNzgxZWI4OTZjODJkMDQ2YTA4MDY3YTExZTM1Y2RmMmYxZGZhZjI2ZmVhOTBiOGRiNjY3NjQxMyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiNmM0ZjYxZDRhYTM3OTExNDhhNTI0ZmY3MDZhYTlhODYyNDAwNmQ0Y2ExMjNlYzc1ZThiNDM5NGViZmRiN2E5ZSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiOGQ1ZDNmZWNjMzhiODZlYzZjNWUzZTYwYjcwZTE4ZTE3NjAxMmY0OTI5YjdkYWQ4YmE2Zjk5NDgxMDI2YzEyZCJ9"
}
]
},
{
"id": "claim_f9e8d9bee95d4852b43c8f24f2ffae66",
"statement": "AgentToolPresentationProfileTests verifies injected phase/detail/approval/truncation policy and custom vocabulary, ID-based profile selection without name recovery, and MCP isolation while allowing explicitly supplied projection.",
"statement": "AgentToolPresentationProfileTests verifies injected phase/detail/approval/truncation policy and custom vocabulary, registered-ID profile selection across a tool rename and no name recovery for unknown or absent IDs. Its MCP regression verifies rejection of a local SSH presenter ID from remote metadata, generic Value-field fallback, and explicitly supplied Projected-field presentation with caller-supplied layout.",
"evidence": [
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift",
"version": "repo-file-v1:sha256:2f2610b7c2271c5954f502680d5eb22b332bf8a2bdeb186b0833d12381080400"
"version": "repo-file-v1:sha256:cb1090f8c675d0529f3272dd539535376fb272022501ea6043cb6ad4250646f2"
}
]
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:25366a8e74c698b47e7c7a80c511bd6df72ee3f89a9f93e7ae6de2c2aeb4de3a",
"pageVersion": "sha256:c792778ce74a498a05bea3f319dfdc0ad71ca432a8189f88e8c2a9b732e49913",
"claims": [
{
"id": "claim_981f16f030e9469588af705aa377161e",
@@ -748,11 +748,31 @@
},
{
"id": "claim_b13dacae7f2f40f38238d00735614941",
"statement": "Approval projects in-memory arguments without persisting that projection; ordinary built-in details use structured presenters or generic fallback, while MCP bypasses local presenters and retains remote output. Local collaboration tools instead require presenter-based approval arguments and use safe unavailable-details fallback for missing or failed detail data.",
"statement": "Approval projects in-memory arguments without persisting that projection. MCP descriptors cannot resolve local executable presenters; their empty presentation profiles permit generic structured detail fallback, while trusted callers can explicitly inject a presenter whose projection and layout the renderer uses even for MCP. Local pane and chat privacy profiles apply independently of presenter availability, including local-name selection with missing or unknown IDs, without recovering executable presenter identity: pane details remain metadata-only, and chat tools require projected approval arguments and safe unavailable-details fallback rather than raw chat bodies. These display policies do not rewrite replay payloads.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift",
"version": "repo-file-v1:sha256:7e73ee136dbf26955f003be86adb8b83dee3914c18012efa5bb5e2a45db83351"
"resource": "repo://Frameworks/TermindPresentation/AgentChatToolPresentation.swift#L12-L39",
"version": "repo-lines-v1:sha256:294ba86e431cac37de9f8502fb5be1f7fac2a6070956804c999f8451626ba1e4:eyJzZWxlY3RlZExpbmVDb3VudCI6MjgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImEwOWI1YmVmOTc4NjhhNzUxMTFhZjJjNzg3NDI3MDI0NDY4ZGVmNmY5OTM5MTFhODc1ODM2OGI2MTM1OTE5ZmIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM1MDNiODdiNDAzOTg2ZjlmMGE1MGZmNTI2MTFlMzJhOTI1NjI2MzU4ZjQ3YWNhY2MzNDc2ZWMwZGVlYzdmNjIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImY1NDIwNjRmYjZhOWEyYmE4MmEzY2I2NTY0ODFmYzEzNWJhZjFlZmMxOGQ4OTQyNDYxYmZiODIwYWI4Mzk4NzkiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoyLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjM3OTRkMDJhODEyMTk0NGQxNzZkMjY1ZTliYjljYzU5ZjZhYjg5MGJjYWRmOGFlZmRlYmRiYmI0ZjJlYTg0NDQifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentPaneToolPresentation.swift#L33-L76",
"version": "repo-lines-v1:sha256:f8cfac3764b34ff050a6a10304f67eb970bd6d5027a93218ab90298c54026613:eyJzZWxlY3RlZExpbmVDb3VudCI6NDQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjdjNDQ4ZTQyZjc0NWI3ZThjOTZmNjg4YzYyNzE2NzM1MjVlYmM2OTZlNjMyY2NhYTc1OTNkMzQ4Mjk3ZjRmYzgiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRiYzg2Y2EzMzVlNzIyOTY5NzNmZmI2NTJjNTkzMzljZjIwMTQxNTcyNTA1NmFiNTk1MzQ2MWU2YjI0ODAwNWIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImJhOTIzZDYzZDViZTc0YmJkZmIxN2Q2ODJmYTlkZTJkNjY1M2VkYjcwODQ5OGE3YmIwMDBiYTc2ZWM1ODY1ZmEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjU0YjEzMTRjNGU0MjQzMDUxNzE0YzYxZGMxMmVkNTdlMzU2OTc2MzAxMDJmMjVkMDIxOGI3NzhiNWUyMDBlZDUifQ"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift#L312-L413",
"version": "repo-lines-v1:sha256:d7229be74574cd765193541e9b2366662dbc36f9fdf9f12dd2b0418b489593af:eyJzZWxlY3RlZExpbmVDb3VudCI6MTAyLCJmaXJzdFNlbGVjdGVkTGluZUhhc2giOiJiM2UxMjBkZTg2MzVmZWNlZDVjMWEwOGE3NmMwMzg4YTYwMmM0ZTVlYmQ2MjVlOTRlZmEzY2Y5ODNkMDg0ZDNkIiwibGFzdFNlbGVjdGVkTGluZUhhc2giOiJiMWM1MTEwNWNhNTY5MGUzNGM4ZTUzOTg1ZmI0NjhhNTU1MmNmYzVkYWIzOTk5ZDU2ZTllNWJhN2RmMDMyMGRkIiwicHJlY2VkaW5nQ29udGV4dExpbmVDb3VudCI6MywicHJlY2VkaW5nQ29udGV4dEhhc2giOiI2OGFjZTliNzVmMmVkOWU0YjA5ODU2ZTRiY2IxYTAyYjM1Yzc2NTM0Yzc4YmYzNDI2ZWI5ZWFkMTVjNmJlMmEwIiwiZm9sbG93aW5nQ29udGV4dExpbmVDb3VudCI6MywiZm9sbG93aW5nQ29udGV4dEhhc2giOiJiNWY0ZTRiMjlhZjQ0MmNiNjQ2YjU0NjdlN2YxYzhiZDQ5ZjlkZTI2YWI0Y2YyNTgxZmEwMzBjMmZhMTQ2YjdiIn0"
},
{
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift#L25-L38",
"version": "repo-lines-v1:sha256:6a657a430947e742759792a69e15ae5a86af0c33f248e517e7c7a2aa9efb7df7:eyJzZWxlY3RlZExpbmVDb3VudCI6MTQsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU3MjE3OGJiOTBhNjc4MmVjNWM3NGIwZDMzMDhjMzc5YzUxYjUwYTgwYmUwMzc1Y2VmNWYzYjFlNDA2Y2VjZWIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6Ijk3NDFmMzk5NTFhOGRhNzAzMzFlMDJjZmRkMzQwZjAxYzZiNTVkZThhNmE3Yjk2OTRkNTg0MDQ1ZDExYjY0NjQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjoxLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjQxMmNhMzQ1Y2NmNzViZjljMDgwNmJjZTY5NWJlOGRlODA4Yjc5OTg0MjUxYTdhNTRkMjAyY2Y2MTAxZGQ0NTEifQ"
},
{
"resource": "repo://Frameworks/TermindRemoteInfrastructure/Agent/TermindAgentTools.swift#L60-L74",
"version": "repo-lines-v1:sha256:cc6484a13635f00edc8c77582bbf0fd425ace1d2d566a90118292db8ec786eec:eyJzZWxlY3RlZExpbmVDb3VudCI6MTUsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjkyZDMzMDFlNWE3MGRjYTk1NjFjNjY4NWE4NjdhNDAwNWFkYjM2ZTg3Nzk4ZjkxYWY1ODY2NTRmNTFkYTAwZjYiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjVmZDhkYmMxYWQ0N2NmOTVhNGRkMGUzZThjNDg1MGFmZjkwMTRiMmE5ZDZlYzJiYmQ0Njg2ZmEwYTk2NGMxMWEiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6ImVjNmNiNzk1N2Y1ODdiZjMyMWE1NDgxOTFlMTEzYjlkZDBjYzdhM2M3ODU1NjQ1ZjQxZGExMDg4MmVlYmFlYjAifQ"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L63-L104",
"version": "repo-lines-v1:sha256:20e1f32bc70380288cfdb784dcd2ca22a5bc94e180636d6b202fd6919a87f571:eyJzZWxlY3RlZExpbmVDb3VudCI6NDIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
}
]
},
@@ -1266,7 +1286,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:6dcd715ee64e0f4a9f9be3d03792e660181e0b142dcd5a73ed5ec0c435602b03",
"pageVersion": "sha256:c80dc54f833b9efa943663f673459a54d4747c4bdb86a9a3acb64996c3efe7ae",
"claims": [
{
"id": "claim_e50b505da2214c6781fa8eb1a146dacf",
@@ -1252,19 +1252,31 @@
},
{
"id": "claim_ac2d9e510688466381f090671c50fbf4",
"statement": "The app's tool-result persistence wrapper applies AgentSecretLifecycle before delegating to AgentSensitiveDataRedactor.toolResultText; tool-role frozen model text uses the same path. Restore replaces malformed structured-looking text only with a valid structured fallback, otherwise retains it. The inspected resolved-package snapshot replaces request_user_secret output with an expired single-use envelope but lacks the current toolResultText redactor API, so its structural-redaction, framing and sizing internals are not verified by that snapshot.",
"statement": "The app's durable tool-result and tool-role frozen-model-text writers apply AgentSecretLifecycle.persistedResultText before AgentSensitiveDataRedactor.toolResultText. Restore repairs structured-looking text only when decoding fails and a structured fallback decodes successfully, otherwise retaining the original; repository callers use durable result content and frozen model content as fallbacks. Focused replay fixtures assert that persisted request_user_secret output has expired handle status with no handle field or original handle string, and that malformed wrapped output recovers a frozen structured preview while plain output remains unchanged. These establish app-facing contracts, not inspected AgentKit redaction, envelope or sizing internals; Package.resolved identifies AgentKit 4.0.0 at revision 3481866cd47e83f6bf56b80c432c7824f61130b9 from https://github.com/AkinoKaede/AgentKit.git but is evidence of dependency identity only.",
"evidence": [
{
"resource": "repo://.build/fastlane-screenshots/mac/SourcePackages/checkouts/AgentKit/Sources/AgentKit/Security/AgentSensitiveDataRedactor.swift",
"version": "repo-file-v1:sha256:534d2d3402215ebb3e946a8b539fd52868305a33e948de9320f9088bdb69a638"
"resource": "repo://FrameworkTests/AgentReplayPersistenceTests.swift#L76-L115",
"version": "repo-lines-v1:sha256:cb4dfffe6da41809ef75d4bb8ab2a609e63d1d5e6ccbead05d578af233edcbd7:eyJzZWxlY3RlZExpbmVDb3VudCI6NDAsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImY4ZmRiMWE0ZmJiNDNlODMyMWI3MmU0Y2Y1ZmI2MDViMzJjMGRhMDlmMDVjZjQ2NjRkOTk1ZWFhYWZmZjk3YjAiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImE3YTJiYWYxMjA1ZDE2OTUzOGVjMWE5MTljMTg2NTc2N2M4YzJkMDg1NmQzOTJlM2RmZDhhNjIwYjQ0OTdjNGIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjE3MzgwYmYzNGNkYmJjNGVmODdiMWZhMTc2NWNiYTY1OTFiZGJmODk4ZDAzOGNkNmY2MDg5YTAxYzUxNGU3MzEifQ"
},
{
"resource": "repo://Frameworks/TermindPersistence/AgentPersistenceRedactor.swift",
"version": "repo-file-v1:sha256:22ed7d9ae648108859afdfc4047541e62a1747c17944f91596696837f561d994"
"resource": "repo://Frameworks/TermindPersistence/AgentPersistence.swift#L214-L235",
"version": "repo-lines-v1:sha256:bf871bcaf0e3c31c2d35ad38c1a447b3fea54011eaea28c1f9d1287676d4ee63:eyJzZWxlY3RlZExpbmVDb3VudCI6MjIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRkY2FlZmNjZTgyYTkzMTMzY2VkNzE3MWFiZjkyNmQ4MzViN2U5ZGNjNGE3ODFhMmMzZDIzZDVhNTg3ZTMyNDciLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6Ijc3MmY5Njk1Yzc0NjdjNzQ3NzNjOWNlN2ZjNDI5YzVkMGQwZTQ4N2YzYzUxZDE1ZDY2NjhhM2QyNDA3MmJiOTUiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjYzOWZhYmM2YzFjMWFmMjhiYjJiMGVmMjgxY2Q0YWEwNGM1NjJkMzc5ODdmMmZiMjBjZGRmZDI3NDAzYmU5ZTAiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjE5ZTc2MzU1Y2YxMTk5NDgwYzNmOTk4MzZiMTQ4NmM4NDFkODkxZmFhZDkwNGM2MDhlMDkzMDIyZDM3NTdhZWUifQ"
},
{
"resource": "repo://Frameworks/TermindPersistence/AgentPersistenceRedactor.swift#L15-L30",
"version": "repo-lines-v1:sha256:e7a12356b37c2f736b3143ee59bf8d5a4e7a161ab786ab12c99ed9c1b7a18063:eyJzZWxlY3RlZExpbmVDb3VudCI6MTYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImY0MzZmY2NlODQ0YmUwYzQ5ZGFmNGMyYzE4MzU3YTkxMjI1NjEzZWMxZDFhOWVmOGM4OGNlMTEyNTNlNzg1NDIiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjM0M2ZjZjU0YjYxOTcyYTdhNmQ4NDhhYjk4MjZlYTY3OGE3NTU0MzE5ZmYzMTc2YzNkNzRhYjU2ZDk0M2UzMzIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjJkYTVhZWRiNGRiNjJmNjJjZTBhZmM1NGQ3MTMwOGE3YWU5ZmI4ZWQ5YzYwODlmMjA2OTRhNDI2NjYzNWQ0NGIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjdhYTYwMzAwN2U5NzJjZjcxZGM0OWFhZTM3NTUyMzlmYWJjMTY3YTkyYjYxZmRmYzJhYWNiYWIyMmJjZDk5YjYifQ"
},
{
"resource": "repo://Frameworks/TermindPersistence/PersistentAgentMessageReplay.swift#L12-L19",
"version": "repo-lines-v1:sha256:ac48df502207696afa0999a04a0f18de579965bb3f802325dd344c041e58dad3:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZTU2Yzk1ZTFiNTQ5MzAxNTM0ZjQ5ODIzMGMxMjUzZmM2OGQ1ZjgyZDA4MTcwMTJhZTlmZDBlYTZlNjNkODk2MSIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiZTZiMDQ0OTE0Njk3MjJlODM2M2E5NGU0MDQ0NTM4ZTAxM2EyYTIxN2UzNmIxZTU2OGJhNjBhY2I3YjRjOGYyZSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiOWJkNzJhODQyOWZmMzk5ZTZlYzU0MWFjOTlkYzYwMmRhMzA3Zjk3ZDk2ZjcwMjZmZjRlODgyNTdjODgxYTg1MyIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiNmYzMzg4MmJiODM2NzI4YjZkYmM4NDFkMzQ1NzJjOGI5OTAyOGM4ZDQxMGU5ZTIyNDlmNGU5ZjE1MWUxNWVkYyJ9"
},
{
"resource": "repo://Frameworks/TermindPersistence/SwiftDataAgentRunRepository.swift#L250-L260",
"version": "repo-lines-v1:sha256:ca406f599e46036af6d8dfbd97926fc796fce7e5d6d862d29e4e74bb6fb813b1:eyJzZWxlY3RlZExpbmVDb3VudCI6MTEsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6ImFhOTg5MTFkYjEwYTUzOWU5OTk4MjBiOTU3YmM4NzIyNjFlM2NjMzY2NmYyZjQwNmUwZmRhMGI1ZjkzNDlmNWUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjYyYTM5N2FlOThiZGI4Y2MyMzFmYWQ1ZTA0NzJhMDlmY2FhMmQzMTgwODI0OWU2Mjc1YTVmOTA5ZDE2ZDRjODMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6IjJmZjVjYTdhZTY5OGYzMWFhOGZmZDdlNTc1ZmRhMzQ1OWNhNThjMmFmMDMwYTlhMDQzNDdkMjJkMjJiNjdkYTQiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjEwMDdlZDQyNDM2Y2ZkY2QyYzNhNmJlMWI2MzIwZDY3ZGUwYjkwNmRmOTM5M2ExYWQ1NjNlMzkyZGQ1NDI5ODkifQ"
},
{
"resource": "repo://Termind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved#L13-L20",
"version": "repo-lines-v1:sha256:1dd7810c283a6d3810b805e83b97bb553a23b6c765512d8550b58493b2ef485c:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZjljYTg5MWJmZjdhYzFmN2NlYWFlNDBlZjA1MTA2NmJlOWVmZTQ3YjRlNDI4MWU4NmMzMTliZTJjNTVlYmNlNCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiOWI2MmY2MGQ4NTkwYTU3OWNmNDZmOGQ2NzM3OGM0YzU3MmI5NjJjZWNjZGI5MGM3YTVmN2I0MmI5NjA3ODJhNCIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiM2I0YjBlOGY4M2ZlMjRlYTU1MDViMjMwM2E1ZDMyY2EyNzcxM2U5ZWMzOWU5MDA1OGIwNmMyM2E1OTI5MzI5OSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiZWVhODk3OTUzOTRmN2RjZjViOGIyMTMzMTY5MDU1YmUxMjBmZjBiMTc4NDgzZDEwNTAyZjc2MGE2YjgzNGQxYyJ9"
}
]
},
@@ -1316,7 +1328,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:8ab91fc623ef6c68a98f5fa1f00adb0cedd32b4dd6c601cbf6a4a30ed62abcdd",
"pageVersion": "sha256:47c52e17b347b20e5b87b50692b34bb9efd35b555a60818c1d5dcc56373e5501",
"claims": [
{
"id": "claim_3a403468456840acbfe0a524b90d5717",
@@ -556,19 +556,15 @@
},
{
"id": "claim_f8e11156b4024feea9bd224c69a504eb",
"statement": "Tool presentation leaves original execution/replay data unchanged. Approval projects in-memory request arguments rather than durable cards/model transcripts, requiring restricted chat argument projection. Ordinary JSON failures pass failure state to presenters; knowledge tests reject success messages on failure. Typed previews retain full items and desktop disclosure is per-card with selectable native labels.",
"statement": "Presentation leaves execution/replay data unchanged and projects live approval arguments separately from durable cards/model transcripts, with required projection failing closed. Ordinary JSON presenters receive failure state; knowledge tests reject success messages on failure. Previews preserve full projected items, desktop disclosure is keyed per card, and native plain detail values are selectable.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentChatToolPresentation.swift",
"version": "repo-file-v1:sha256:aded24151ee24b9b43d765700259fa13a3e4817494815c1c47ce39aef41fd0b3"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift",
"version": "repo-file-v1:sha256:7e73ee136dbf26955f003be86adb8b83dee3914c18012efa5bb5e2a45db83351"
},
{
"resource": "repo://TFM/Features/AI/TranscriptNativeRows.swift",
"version": "repo-file-v1:sha256:892ccf10c9500ad120421878cc60911c1c56735eca81cad8a5fb2bccfd4ce67e"
"resource": "repo://TFM/Features/AI/TranscriptNativeRows.swift#L1505-L1613",
"version": "repo-lines-v1:sha256:15d4698aa5fb273d5bac3604777a5a9ec056b32649415cbf74167afd103ce452:eyJzZWxlY3RlZExpbmVDb3VudCI6MTA5LCJmaXJzdFNlbGVjdGVkTGluZUhhc2giOiIzYzY4M2I4YWFjNGUzNDhhNDdkN2NjNmI1YmVlMGYyNjgwMTg0YTQwMjM5MjljOTg3NjA1YzdiNTZkYTQwODhhIiwibGFzdFNlbGVjdGVkTGluZUhhc2giOiI3ZmU0M2MzNzM5ODdlNGNkYmQwYmY1MTQzODAwMzhiNzQ1ZjBmOTY1NDI0YzMxNTdlYmM3YzE0MmZjM2M0ZWYyIiwicHJlY2VkaW5nQ29udGV4dExpbmVDb3VudCI6MywicHJlY2VkaW5nQ29udGV4dEhhc2giOiJhZGUwMmRlNTA2ZDc4Mzc0ZGY0NTQ5YTAyZmM5ODBjZDYwN2E3MzY4Nzg3Y2FkMWJjZTE2ZDYwYmU5NzU3OTkyIiwiZm9sbG93aW5nQ29udGV4dExpbmVDb3VudCI6MywiZm9sbG93aW5nQ29udGV4dEhhc2giOiI3NzI4MTk2YzY1MWJmMjJhM2FjNGE0Y2QxYzM1MmNiMDNmYjRlODY4N2JkYmRhYTVkZmZhMmU5MmE2MGQ0ZmFhIn0"
},
{
"resource": "repo://TFMTests/AgentKnowledgeToolPresentationTests.swift",
@@ -926,33 +922,33 @@
},
{
"id": "claim_ba66177813594d9fa99ec461ec18b5d4",
"statement": "AgentToolPresentation accepts injected profiles and vocabulary; profiles override summaries, operations, batches, phases, details and truncation policy, and distinguish hidden details from default fallback.",
"statement": "AgentToolPresentation accepts injected profiles and vocabulary; profiles override summaries, operations, batches, phases, details and truncation policy, distinguishing hidden details from fallback. Shared SwiftUI and native detail fields place secondary labels above values, omit empty value views, prioritize navigation over URLs, and color plain error values red without overriding message tints or link styling. AssistantToolDetails enables selection and renders retained items without folding; approval renders all projected arguments while only safety reasons fold. Compact wrappers own preview/full selection rather than the item renderer.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentation.swift",
"version": "repo-file-v1:sha256:7e73ee136dbf26955f003be86adb8b83dee3914c18012efa5bb5e2a45db83351"
"resource": "repo://Frameworks/TermindPresentation/AssistantToolDetails.swift",
"version": "repo-file-v1:sha256:b0fb548446d48acc524a605d4d09fa6233d1258f2a1703e8eb7b7f713454b93f"
},
{
"resource": "repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift",
"version": "repo-file-v1:sha256:1937a7d0ca1dc86e3777b9457193d92c761f79b59ce221e28377ae89fe3d6eed"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift",
"version": "repo-file-v1:sha256:2f2610b7c2271c5954f502680d5eb22b332bf8a2bdeb186b0833d12381080400"
"resource": "repo://TFM/Features/AI/TranscriptNativeRows.swift#L1543-L1613",
"version": "repo-lines-v1:sha256:68d3760c380793e0c011ec251c5a8add3b766db2cee7f50f8b5f454658e9b8be:eyJzZWxlY3RlZExpbmVDb3VudCI6NzEsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjlmMzc0ZGRlMDNjMWYxNDAxMzQyMWY2NWQ2ZGE4MTMyZGQxZTEyYjQ3MzQyYTkyODk1MmY2NWRkN2I0MjMwN2YiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjdmZTQzYzM3Mzk4N2U0Y2RiZDBiZjUxNDM4MDAzOGI3NDVmMGY5NjU0MjRjMzE1N2ViYzdjMTQyZmMzYzRlZjIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImE5NmNkN2Y0OGMwOTRlYjg0YzJiNDcwMDQ2MmYxYjU1ZjdmNGQwMWNlYWIwYTIwNjJkM2Q4NjdlNGUxNDBlNDgiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6Ijc3MjgxOTZjNjUxYmYyMmEzYWM0YTRjZDFjMzUyY2IwM2ZiNGU4Njg3YmRiZGFhNWRmZmEyZTkyYTYwZDRmYWEifQ"
}
]
},
{
"id": "claim_104842d314fd47b4b6228bf3dd103a8c",
"statement": "TermindToolPresentationProfiles composes registered policies by presenter ID, leaves unknown IDs generic, applies local pane/chat privacy independently of presenter availability and keeps MCP JSON unless a caller explicitly supplies a presenter; remote metadata cannot select local executable presentation code.",
"statement": "Trusted composition selects registered profiles by presenter ID with independent local pane/chat privacy, while MCP receives a default profile and decoded JSON falls back to generic structured items. An explicitly injected trusted presenter can supply typed items and layout; remote metadata cannot select local code.",
"evidence": [
{
"resource": "repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift",
"version": "repo-file-v1:sha256:c9d67b4b871d3bbd2c7dc81ca1f5382f812f6bb90607fd068a9e3edd3ccfbd0a"
"version": "repo-file-v1:sha256:fd9e4be4c236ac64d433a68887986d4decd57b9ad1e8f5d34579da00ae6de729"
},
{
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L63-L104",
"version": "repo-lines-v1:sha256:2e683a7cfc6d1a0324b452c5e5cc75140e46613ecc04f2f42bf371828fbd836a:eyJzZWxlY3RlZExpbmVDb3VudCI6NDIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
"version": "repo-lines-v1:sha256:20e1f32bc70380288cfdb784dcd2ca22a5bc94e180636d6b202fd6919a87f571:eyJzZWxlY3RlZExpbmVDb3VudCI6NDIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
},
{
"resource": "repo://TFMTests/AgentToolPresentationTests.swift#L283-L310",
"version": "repo-lines-v1:sha256:8fb15602a68fef076df3a794f3f52cf9238b3399e7b957257d807284bf012b3c:eyJzZWxlY3RlZExpbmVDb3VudCI6MjgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjI4Y2VjYWViOTIwM2FiNzllYjVlOTcyMjE4Mzk4ZmUxM2IyN2JmNTNhYmMyMDU3NzAyOTYxNzMzOTdkMTcxY2QiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImU4ZWFmM2UxZGIyODRmNmE2ZmQ0ZTA2NmFlMmZiNjU0YWU2OGZkZmNmM2U3ZTRkY2E0YzJkZDIxNGE0OWI5ZDAiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjYyZjE1MDQwMTExNjljZDg2OTYzMTM3YTI4YjM0ZTU5MmQxNWIzMzUwOTQ5NjU1MDM5NzI2NDYyMzM2NDQyMDYifQ"
}
]
},
@@ -972,7 +968,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:9c2a8d3d3f1bf67cbd00cd71d6afde8cc9782ae4ceb442fd7961c7d2c0075076",
"pageVersion": "sha256:81168582d9706d63b676a8c1167c6bc365e4dcf4a799a28ceb5846fae0087cbc",
"claims": [
{
"id": "claim_d34d7b16495a44a4a946d3dc9e0456f4",
@@ -104,19 +104,19 @@
},
{
"id": "claim_9001476115de4dc3a10921fa323b9f08",
"statement": "The independent website submodule is optional for native builds; its README requires Node.js 22.12 or newer and its manifest defines dev as astro dev, build as astro check && astro build, and test:locales as the locale-check script to run after building.",
"statement": "AGENTS.md identifies com.akinokaede.termind as an independent Astro website/assets submodule optional for native builds and documents npm ci && npm run dev for local development and npm run build for type-checking and production output; .gitmodules declares its initialization path and public HTTPS clone URL. Node requirements and additional scripts must be verified in the initialized independent project rather than inferred from parent guidance.",
"evidence": [
{
"resource": "repo://AGENTS.md",
"version": "repo-file-v1:sha256:c89745f5cc73443900b30c7f9e646bf8041160463726478986de47e183ddd8c0"
"resource": "repo://.gitmodules#L1-L3",
"version": "repo-lines-v1:sha256:c7d6ce76620da3eafc5c9b3ec573712bd83321c656fdee9b33e1623600ee21cc:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZDVlZTM0ZTU3NWVjNjRhODEzMjliZTk1ZWEwZDk3MTFhMTg0MDQ1MTRiNjkyMjhmNDMzODlhOGQ4ZjJjMWUxOCIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiOGM4NDY1YjI4NDNjZjc3ZTlmMTE5M2IzOTc0OGMyNjZkYmM5NjJhZGY0ZTlhYjVhMTAxYzcxYTdkYzlhNDlmMCIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjAsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NSIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjAsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiZTNiMGM0NDI5OGZjMWMxNDlhZmJmNGM4OTk2ZmI5MjQyN2FlNDFlNDY0OWI5MzRjYTQ5NTk5MWI3ODUyYjg1NSJ9"
},
{
"resource": "repo://com.akinokaede.termind/README.md",
"version": "repo-file-v1:sha256:fd291f44a8af8e9409e8c3b87a0262cd7152fbca5b075cc751bd16b859cd3253"
"resource": "repo://AGENTS.md#L14-L21",
"version": "repo-lines-v1:sha256:f7006ba5333ec8f892401084d297a5cca1441539d4981caa353aa0b7fcc540d7:eyJzZWxlY3RlZExpbmVDb3VudCI6OCwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiMjEwYTA3YWY5NGUwMTJmZmRmZWYyZjAwOTkyN2MwODg0OTJhNGYzY2UzZmQxOWUxYjlkNDFhNTkyMTU3YTg0ZiIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiZmQwODIwM2ZlMmM4ZDNlNmNkZDgxODZiNWI0NDcwMjNkOGI3MTgzOWM5OWY0OGVkNTE2MjBiZjc2NzNiYTEwNyIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZTk5ZGM1ZDdjMzBhMTNiZGUzZjdmNjg5MTdhMmRlMDMwOTc3M2IzMDJmM2JjMzU0NWI1MWY2NjM1MTUxNDY5MCIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiMzI1MGE3ODNiYTRmYzRkOTViNmQ3MDgwMjA5NDYyZWQ4NTRlMTJhZjAwZDhkMjI1Mjk1ZDc1NzY2ZmZhODZhNyJ9"
},
{
"resource": "repo://com.akinokaede.termind/package.json",
"version": "repo-file-v1:sha256:a30aca1b31ece28759f8773d1646c87ab554579516d785d90d2225320684ae7f"
"resource": "repo://AGENTS.md#L38-L43",
"version": "repo-lines-v1:sha256:d530e1e2a01b97c3be0aefe86a311d47b7ffa1713bbf696cfb47dc54a1b3a838:eyJzZWxlY3RlZExpbmVDb3VudCI6NiwiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiZGZmNDZjMmQzNzgwODk3OGE4MzcyMDg4MDIzOGEzMjEzM2U3OTlkMmJlNGQwMWQzYjUyN2IxNjg2NThiMWIxMyIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiOWZhOTJmZDQyNWYwN2ViMmIyMWVmN2FjZWM2YmNkZWNkYTZmNzk0MWM1OTI5M2U4YzYyMmRiMjhjOGU4YWY2ZCIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZjQyY2VmZTE0YWM1YTBmNTZjNDQwMzQxMjk5NWEwMjBmYmIxZmNlYjkxNzM0ZWJmOWU2MmJlYTJjNDU1Y2IxNiIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiNTMwM2VlYzhlNjU1MjZiMzI1MWUyNDRmNjljMGIwOTMwY2ZmNTFiZDhiODRkMzZhMzk1NzJlZDg3YjIyOWZkOSJ9"
}
]
},
@@ -376,15 +376,11 @@
},
{
"id": "claim_69843718608d4e2c81ad7d770de060cf",
"statement": "Parent guidance requires web production builds and English and /zh/ visual review; the website README documents seven current locale roots and legacy /zh/ redirects to Simplified Chinese, so parent guidance is not the complete current route inventory.",
"statement": "Parent guidance requires web changes to pass npm run build and receive visual review of English and /zh/ routes; it does not establish a full current website locale inventory or redirect contract, which must be verified in the initialized independent project.",
"evidence": [
{
"resource": "repo://AGENTS.md",
"version": "repo-file-v1:sha256:c89745f5cc73443900b30c7f9e646bf8041160463726478986de47e183ddd8c0"
},
{
"resource": "repo://com.akinokaede.termind/README.md",
"version": "repo-file-v1:sha256:fd291f44a8af8e9409e8c3b87a0262cd7152fbca5b075cc751bd16b859cd3253"
"resource": "repo://AGENTS.md#L49-L51",
"version": "repo-lines-v1:sha256:6997a1a7c8b75f5e00768cec37c6a6baf7027c2733ed3a9a1a5cb3e483809e4d:eyJzZWxlY3RlZExpbmVDb3VudCI6MywiZmlyc3RTZWxlY3RlZExpbmVIYXNoIjoiOTdmYzk4NmVmMDFlZTVmNThjNmYxZmEyNjViOGE2NDEzMTE2OGY4YWE1OTkzZDc4ODZkOTZjNmUxODk4OTQzMiIsImxhc3RTZWxlY3RlZExpbmVIYXNoIjoiM2VkMDNiODMzODVkNTYyYTZmN2VhN2FjNzljMDRjOTAyYjliNDc1YmU2ZGRmMGJmZWU4NmJmNGY1MWYxMTAyOSIsInByZWNlZGluZ0NvbnRleHRMaW5lQ291bnQiOjMsInByZWNlZGluZ0NvbnRleHRIYXNoIjoiZDFkYTg3Nzk4Y2M5NTc1N2I3NzQ0NThlYzQ5Yjg0MWRjYWMzODA1MWQ5MjljZGI5ODE5MGJiMTdiMjdkZmQ4OCIsImZvbGxvd2luZ0NvbnRleHRMaW5lQ291bnQiOjMsImZvbGxvd2luZ0NvbnRleHRIYXNoIjoiNjBlZjRjY2FhNGI0NTRlNjA4YTJkMmI1YzIyOTk4OThlMjQ1MGE5OTJlMWI3MmI4M2EzMGI3ZjFlMWJhMjE5MCJ9"
}
]
},
@@ -566,7 +562,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T04:32:02.799Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:868588fcb121de52351fccbae3637078213f4f3c5d2421fae434a1f576230ac3",
"pageVersion": "sha256:4e0377a70de3d6ae1ad91a9adc6f6305a1998c624740e9c6239fdf3aefd44717",
"claims": [
{
"id": "claim_bf6e7f1d333040099a25edc9d0d96b84",
@@ -346,19 +346,15 @@
},
{
"id": "claim_e071a72be59c4afbaa7b520a182c3817",
"statement": "Paywall illustrations belong to external design/paywall assets. Native MobileProView and ProPaywallView embed RevenueCatUI.PaywallView when using RevenueCat; editing external illustration files does not publish the remote paywall.",
"statement": "Native MobileProView and ProPaywallView embed RevenueCatUI.PaywallView when using RevenueCat rather than loading illustration files from the external assets checkout; editing external handoff artwork does not publish the remote paywall.",
"evidence": [
{
"resource": "repo://TFI/Features/Commerce/MobileProView.swift",
"version": "repo-file-v1:sha256:5f7c8bae7a5301bdc33db6ee4fab0216cf9e5cef2fd75e31f37ac3f990eb278a"
"resource": "repo://TFI/Features/Commerce/MobileProView.swift#L1-L46",
"version": "repo-lines-v1:sha256:9da2344e7a2671e5c1295b5222d144527945be46e7e06862f2a02525a7831125:eyJzZWxlY3RlZExpbmVDb3VudCI6NDYsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA3ZTMzZDQ4NTU2ZjNmYjBlMmIzYTdhOThjMTkyMzlhZTU3ZGE4YTVmNGI1ZDAxNWNkNjA5YWEyYzIxNjk2MzciLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU1MjJjNDJjZDE5YzZkMDNkODA4YzQ1MjcyMDU1MjgyNWI3ZWExYzViNDkxYjIxODUxMWNhYzc0MTVjZjlkOWIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjowLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImUzYjBjNDQyOThmYzFjMTQ5YWZiZjRjODk5NmZiOTI0MjdhZTQxZTQ2NDliOTM0Y2E0OTU5OTFiNzg1MmI4NTUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjU3ZDE3OTA1ZWJkZjk4YWMxNGVmN2ZmNzMwYzQ0NDM4ZTIzNTk4NTA0MTUxYWZkN2Q4MWMzMWFkMDU1ZTYwYTEifQ"
},
{
"resource": "repo://TFM/Features/Commerce/ProPaywallView.swift",
"version": "repo-file-v1:sha256:99673b713795d4e35cd5d38d1502ec0bff6b1e0ad516afaa6ffc4b0b5e0dc28b"
},
{
"resource": "repo://com.akinokaede.termind/design/README.md",
"version": "repo-file-v1:sha256:ac12e29e5e342e3f6d5d67b4ee3e6a61c6d45ac83fe818f2eddd7ac703033b7e"
"resource": "repo://TFM/Features/Commerce/ProPaywallView.swift#L1-L48",
"version": "repo-lines-v1:sha256:ac2b3dcd3fc0fdc1787a9d94362a69ddee4ce2a03940c7f467a2a6e543a8bcc0:eyJzZWxlY3RlZExpbmVDb3VudCI6NDgsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjA3ZTMzZDQ4NTU2ZjNmYjBlMmIzYTdhOThjMTkyMzlhZTU3ZGE4YTVmNGI1ZDAxNWNkNjA5YWEyYzIxNjk2MzciLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjU1MjJjNDJjZDE5YzZkMDNkODA4YzQ1MjcyMDU1MjgyNWI3ZWExYzViNDkxYjIxODUxMWNhYzc0MTVjZjlkOWIiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjowLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImUzYjBjNDQyOThmYzFjMTQ5YWZiZjRjODk5NmZiOTI0MjdhZTQxZTQ2NDliOTM0Y2E0OTU5OTFiNzg1MmI4NTUiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjFmNmJmZGJlOTI1NTY3YTczNTQxYjY5MTBhYTA5YWU5MmI2YTk4NDZhN2I1ZThkNjMyZGZkZjk3N2FlNmFiYmEifQ"
}
]
},
@@ -554,20 +550,6 @@
}
]
},
{
"id": "claim_2ac17b98788f451482fca920cbbd5b14",
"statement": "The external asset guide distinguishes final screenshots, header and search_results artwork from captures and device frames; its design guide identifies brand/termind.svg as master and public/brand_mark.svg and public/favicon.svg as website variants.",
"evidence": [
{
"resource": "repo://com.akinokaede.termind/assets/README.md",
"version": "repo-file-v1:sha256:a8407a8d6efec959916d23fde6a288083180b8620da8fed9d64b1d8b964458bf"
},
{
"resource": "repo://com.akinokaede.termind/design/README.md",
"version": "repo-file-v1:sha256:ac12e29e5e342e3f6d5d67b4ee3e6a61c6d45ac83fe818f2eddd7ac703033b7e"
}
]
},
{
"id": "claim_a8d589de90ef4798bf188ce72004a31a",
"statement": "Quiet workflow entrypoints include fastlane screenshot/frame plan:true, syntax checks on the Ruby runners and run-screenshot-demo.sh, and Scripts/check-localization.py; they do not replace opt-in native capture or external visual review.",
@@ -588,7 +570,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T03:39:12.674Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
@@ -1,6 +1,6 @@
{
"schemaVersion": 1,
"pageVersion": "sha256:30b0158f731d5a9878c14ee93826761b06955e7f1ce0a1827db69d391decef43",
"pageVersion": "sha256:06d63f7168adfe6fa9405c23604b42b5e5be7eb6cd6c0ade19df795eecb92d06",
"claims": [
{
"id": "claim_b7fbd64158554b8b8ca80a0a613b3bc3",
@@ -324,11 +324,11 @@
},
{
"id": "claim_78f8d81d663b4c5fb8f7c9ca60534d7b",
"statement": "Tool presentation tests protect the composed AgentKit/Termind presenter ID namespace, presenter-ID-directed restored detail versus generic fallback for missing IDs, safe decoding of old metadata, and approval argument detail including the provided command rather than a blanket redaction guarantee.",
"statement": "Tool presentation tests protect composed presenter-ID uniqueness, ID-directed restored detail versus missing-ID generic fallback, safe old metadata decoding and visible approval arguments. Profile tests additionally reject MCP metadata selecting local code while accepting explicitly supplied presenters, distinguish projected from generic fields, and keep registered semantics ID-based rather than name-based.",
"evidence": [
{
"resource": "repo://TFMTests/AgentToolPresentationTests.swift",
"version": "repo-file-v1:sha256:fbb8fa9a5c629184674d2d7dd105a22f924b26762de2268f0ed3609aa98e0d59"
"resource": "repo://TFMTests/AgentToolPresentationProfileTests.swift#L63-L104",
"version": "repo-lines-v1:sha256:20e1f32bc70380288cfdb784dcd2ca22a5bc94e180636d6b202fd6919a87f571:eyJzZWxlY3RlZExpbmVDb3VudCI6NDIsImZpcnN0U2VsZWN0ZWRMaW5lSGFzaCI6IjRjZjA5ZWIwYzU3NDRmYjk3MzMxYjk4ZmYzZmJmMDVhNjAyYmEzZjdmNjdlNWRhNWJlOTA5NTAzM2Y2MjU4MjUiLCJsYXN0U2VsZWN0ZWRMaW5lSGFzaCI6IjQ4OTNmNDBlMzc4MWViODk2YzgyZDA0NmEwODA2N2ExMWUzNWNkZjJmMWRmYWYyNmZlYTkwYjhkYjY2NzY0MTMiLCJwcmVjZWRpbmdDb250ZXh0TGluZUNvdW50IjozLCJwcmVjZWRpbmdDb250ZXh0SGFzaCI6ImFhMDhmMjE4MzYwYzEyMWRmMmMwNTdjNmFmN2VhMjk5Njc0MzE1YzkwZjU3YzE1Mjk2OWUyODdhY2UyZGQxYTIiLCJmb2xsb3dpbmdDb250ZXh0TGluZUNvdW50IjozLCJmb2xsb3dpbmdDb250ZXh0SGFzaCI6IjNkM2QzYWM4ZmVhMDFhNTUzZDVmOWE0ZmRhZDA5OWE1NjZhYTllN2ZlZjA2NDljYTFjODFhMzljNGVlMDM4YzAifQ"
}
]
},
@@ -1070,7 +1070,7 @@
}
],
"verification": {
"by": "openwiki/0.7.2",
"at": "2026-10-19T04:32:02.799Z"
"by": "openwiki/0.7.0",
"at": "2026-10-19T23:15:37.894Z"
}
}
+3 -3
View File
@@ -1,8 +1,8 @@
{
"updatedAt": "2026-10-19T04:32:56.543Z",
"updatedAt": "2026-10-19T23:26:39.857Z",
"command": "update",
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"model": "host-agent/pi",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"model": "gpt-6-astra",
"status": "complete",
"language": "en"
}
+48 -48
View File
@@ -9,11 +9,11 @@
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
},
"/openwiki/architecture/engineering-invariants.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:83b518f3d06d6183be6cb6a714ca0cb0042666de8d7510a874ef16d382a5e71d",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:f5f9c4a9a57e7bbbc3940fe9327a9cd727922542523d58b86aca97d93d260cdd",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/architecture/mobile-ui.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -37,18 +37,18 @@
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
},
"/openwiki/architecture/system-boundaries.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:cdeb6b232f8ffeb719f49412418183c6ed537f7fd160ee92a36778fe0057e406",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:e22f50b68e7ce28efe8e4bd2a58cd620e5656fbdcb7b466e858f7a2da17a535b",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/concepts/agent-runtime-and-assistant.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:25366a8e74c698b47e7c7a80c511bd6df72ee3f89a9f93e7ae6de2c2aeb4de3a",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:c792778ce74a498a05bea3f319dfdc0ad71ca432a8189f88e8c2a9b732e49913",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/concepts/commerce-localization-and-product-surfaces.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -58,18 +58,18 @@
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
},
"/openwiki/concepts/ghostty-terminal-integration.md": {
"pageVersion": "sha256:bab1690513ca58bf80ff681178a27696cce5e8ebea239ca8650fc0c6ac20e1bc",
"completedBy": "pi",
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc",
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d"
},
"/openwiki/concepts/persistence-and-secrets.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:6dcd715ee64e0f4a9f9be3d03792e660181e0b142dcd5a73ed5ec0c435602b03",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:bab1690513ca58bf80ff681178a27696cce5e8ebea239ca8650fc0c6ac20e1bc",
"completedBy": "pi",
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc"
},
"/openwiki/concepts/persistence-and-secrets.md": {
"pageVersion": "sha256:c80dc54f833b9efa943663f673459a54d4747c4bdb86a9a3acb64996c3efe7ae",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/concepts/remote-services-and-forwarding.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -107,11 +107,11 @@
"completedRunId": "a497c7c7-16a8-404f-a5c0-980b60bd09b6"
},
"/openwiki/concepts/ui-design-principles.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:8ab91fc623ef6c68a98f5fa1f00adb0cedd32b4dd6c601cbf6a4a30ed62abcdd",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:47c52e17b347b20e5b87b50692b34bb9efd35b555a60818c1d5dcc56373e5501",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/integrations/mcp-server-and-bridge.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -135,11 +135,11 @@
"completedRunId": "a497c7c7-16a8-404f-a5c0-980b60bd09b6"
},
"/openwiki/operations/build-test-and-release.md": {
"pageVersion": "sha256:9c2a8d3d3f1bf67cbd00cd71d6afde8cc9782ae4ceb442fd7961c7d2c0075076",
"completedBy": "pi",
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc",
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d"
"pageVersion": "sha256:81168582d9706d63b676a8c1167c6bc365e4dcf4a799a28ceb5846fae0087cbc",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/operations/cloudkit-release-readiness.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -149,11 +149,11 @@
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
},
"/openwiki/operations/marketing-assets-and-app-icons.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:868588fcb121de52351fccbae3637078213f4f3c5d2421fae434a1f576230ac3",
"completedBy": "openwiki/0.7.2",
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
"pageVersion": "sha256:4e0377a70de3d6ae1ad91a9adc6f6305a1998c624740e9c6239fdf3aefd44717",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/operations/port-forwarding-benchmarks.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
@@ -170,18 +170,18 @@
"completedRunId": "f414c8c1-4628-4184-888c-12c20a398a18"
},
"/openwiki/quickstart.md": {
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d",
"pageVersion": "sha256:8087f439ad4f2bf23c3ea9dfa8469a8097995ef29308d155f61b03ed66a4d535",
"completedBy": "pi",
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc",
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d"
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc"
},
"/openwiki/testing/behavioral-boundaries-and-fixtures.md": {
"pageVersion": "sha256:30b0158f731d5a9878c14ee93826761b06955e7f1ce0a1827db69d391decef43",
"completedBy": "pi",
"completedRunId": "a9369c56-5012-4130-9b68-a1e5a08ee5fc",
"gitHead": "4c313ed5fbd0406949a49af2b1e408a206c8fdf2",
"sourceFingerprint": "sha256:1cac225c8e8a5691fbbf5a14db67b801dda6e7cde98165e4f632661eb6d1534d"
"pageVersion": "sha256:06d63f7168adfe6fa9405c23604b42b5e5be7eb6cd6c0ade19df795eecb92d06",
"completedBy": "openwiki/0.7.0",
"completedRunId": "6d8b488d-35a8-4abd-a90d-e165768e2888",
"gitHead": "bbec2db0fbacb2d61c8d4c82191840bff193ee1c",
"sourceFingerprint": "sha256:d0c61c831922504c09cbc0749456856b092b6419f6e848728ac962b018c0fb01"
},
"/openwiki/workflows/desktop-drag-and-drop.md": {
"gitHead": "4216b55d96679fdf330faeae94eb934fe310e400",
@@ -94,6 +94,8 @@ sources:
resource: repo://Frameworks/TermindPresentation/AgentToolDetailPreview.swift
- id: openwiki-source-5b42af91dbdc738123786a99
resource: repo://Frameworks/TermindPresentation/AgentToolPresentation.swift
- id: openwiki-source-7e27e66540bd1ea5c642a652
resource: repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift
- id: openwiki-source-0f9033d291acb89c4894acb9
resource: repo://Frameworks/TermindPresentation/AssistantCompactToolDetails.swift
- id: openwiki-source-0d8bc8948aed7b3cc4944dbf
@@ -240,10 +242,10 @@ sources:
resource: repo://TFMTests/RepositoryOutboxTests.swift
- id: openwiki-source-a08489338be00125d646c77e
resource: repo://TFMTests/VisibleWindowTestTrait.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Engineering Invariants
@@ -411,8 +413,8 @@ Keep the full runtime contract in [Assistant Runtime](../concepts/agent-runtime-
- Preparing cancellation invalidates identity synchronously, joins tracked edit/history/preparation work, then attempts interrupted persistence before projection. `stop()` alone does not wait; drain callers await `stopAndWait()` or cancellation task. Failed save reports error. In `savingFailure`, cancellation joins the existing failed-snapshot save rather than replacing it with interruption. Archive/delete wait; manual compaction refuses preparation; selection alone does not cancel.
- History edits commit truncation before live replacement at the selected canonical user-message boundary. Preserve same-run prefix/tool ownership, neutral completed summary, title and relevant compacted display history; remove suffix/later runs and prune compactions by removed message IDs. Executed suffix tool invocation/result/review rows can be removed; legacy unowned cards belong to the suffix. Agent-provenance user messages remain uneditable. Editing history does not undo remote effects.
- Edited replacement initially owns a same-message-ID staging run. The first real saved snapshot adopts only that staged row and removes staging while preserving chronology and historical replay ownership. Missing-model/credential preparation failures project only after save; failed saves do not adopt staging. Repository-instance retired IDs reject late writes.
- Presentation is not execution data. `AgentToolPresentation` interprets descriptors, lifecycle state and injected profiles/vocabulary without rewriting original calls/results used by execution, approval, persistence or replay. `TermindToolPresentationProfiles` composes tool policies outside the generic renderer: ordinary local semantics follow registered presenter IDs, not guessed tool names, and explicit unknown IDs do not fall back to similarly named tools. Local pane/chat privacy rules remain enforced independently of presenter availability. See [UI Design Principles](../concepts/ui-design-principles.md) and [AgentToolPresentationProfileTests](../../TFMTests/AgentToolPresentationProfileTests.swift).
- Approval arguments are a live local-only projection of original in-memory arguments, never durable cards/transcripts; resolved Host labels and injected presenters can format them without putting commands/paths in short action titles. Local result detail decodes JSON and uses an injected presenter or generic formatting; both app composition roots register localized SSH result presenters through `SSHExecToolPresentation.registering(in:)`, preserving tool-owned layout and approval argument policy. Only result-less SSH cards take the dedicated pending-detail path. MCP keeps remote JSON when no presenter is explicitly supplied. A trusted caller can inject an MCP presenter, but remote descriptor metadata cannot select local executable presentation code. Failure state is passed to built-in presenters so failed knowledge results cannot render success detail; duplicate denial reasons display once. Collaboration exposes only selected fields or safe unavailable detail, never raw fallback; local pane read/list cards show metadata, not terminal output, including replay.
- Presentation is not execution data. `AgentToolPresentation` interprets descriptors, lifecycle state and injected profiles/vocabulary without rewriting original calls/results used by execution, approval, persistence or replay. `TermindToolPresentationProfiles` composes tool policies outside the generic renderer: MCP descriptors receive an empty profile before any local policy lookup; for other targets, ordinary semantics follow registered presenter IDs, not guessed tool names, and missing or unknown IDs use the default profile. The deliberate exception is local pane/chat privacy: name-based privacy rules take precedence over presenter-ID lookup and remain enforced independently of presenter availability. See [UI Design Principles](../concepts/ui-design-principles.md) and [AgentToolPresentationProfileTests](../../TFMTests/AgentToolPresentationProfileTests.swift).
- Approval arguments are a live local-only projection of original in-memory arguments, never durable cards/transcripts; resolved Host labels and injected presenters can format them without putting commands/paths in short action titles. Result detail decodes JSON and uses an injected presenter or generic formatting; both app composition roots register localized SSH result presenters through `SSHExecToolPresentation.registering(in:)`, preserving tool-owned layout and approval argument policy. Only result-less SSH cards take the dedicated pending-detail path. **MCP exclusion is a code-selection boundary, not a raw-JSON rendering requirement.** `TermindAgentTools.presenter(for:)` refuses MCP descriptors even if their metadata names a registered local presenter. With the empty MCP profile and no injected presenter, valid JSON uses generic structured items: the profile test expects `{"value":42}` to become a `Value` field containing `42`, not a raw JSON block. A trusted caller can explicitly inject an MCP presenter and its layout; remote descriptor metadata cannot select that executable code. `explicitMCPPresenterIsUsedButRemoteMetadataCannotSelectLocalCode` covers both paths, while `registeredProfileFollowsItsIDNotTheToolName` covers renamed tools and missing/unknown IDs. Failure state is passed to built-in presenters so failed knowledge results cannot render success detail; duplicate denial reasons display once. Collaboration exposes only selected fields or safe unavailable detail, never raw fallback; local pane read/list cards show metadata, not terminal output, including replay.
- Batch summaries preserve mixed tool/state/knowledge-action outcomes. `AgentToolDetailPreview` shares a five-row and `AgentTruncateLimits.maximumBytes` UTF-8 budget across collapsible text and list bodies, using the presenter's truncation strategy; `.none` bypasses folding. Fields, notices and noncollapsible text are outside that body budget. Full projected items remain available for expansion—not a promised Copy control. Display folding does not invent an output-truncation notice; actual result markers are reused verbatim. Tests: [AssistantTranscriptPresentationTests](../../FrameworkTests/AssistantTranscriptPresentationTests.swift), [AgentKnowledgeToolPresentationTests](../../TFMTests/AgentKnowledgeToolPresentationTests.swift), and [RemoteOutputToolPresentationTests](../../TFMTests/RemoteOutputToolPresentationTests.swift).
## Notifications, preferences and copy
+20 -10
View File
@@ -88,10 +88,10 @@ sources:
resource: repo://TFMTests/ArchitectureBoundaryTests.swift
- id: openwiki-source-c15cd5bef4646aaf64df407e
resource: repo://TFMTests/ConnectionHistoryTests.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# System Boundaries
@@ -303,25 +303,35 @@ Execution registration and localized rendering are separate extension points:
- **Execution availability belongs to the remote catalog.** `TermindAgentTools` registers separate acting and planning variants of SSH run/stdin tools. SFTP mutations and scratch push are acting-only registrations; read-oriented tools remain available without that restriction. Preserve these mode declarations when extending the catalog rather than relying on UI visibility to restrict execution.
- **Localized SSH result rendering belongs to Presentation, assembled by the apps.** Both `AppDependencies` and `MobileAppDependencies` decorate `TermindAgentTools.presenterRegistry` with `SSHExecToolPresentation.registering(in:)`. The decorator replaces selected SSH result projections while retaining persisted presenter IDs, tool-owned layout, and operation policy; argument rendering delegates to the original presenter, falling back to generic argument items if needed. Descriptor lookup first passes through the remote catalog's trusted lookup, which rejects MCP descriptors and requires an explicit registered presenter ID, then selects the decorated presenter by ID. There is no legacy tool-name fallback or separate `ssh_exec`/`ssh_wait` presenter registration. This lets shared Presentation localize results without importing Remote Infrastructure. See the [presentation decorator](../../Frameworks/TermindPresentation/SSHExecToolPresentation.swift) and [desktop composition](../../TFM/App/AppDependencies.swift).
- **Tool-family policy is injected into a generic renderer.** `AgentToolPresentation` interprets descriptor metadata and lifecycle through an injected profile resolver and activity vocabulary, rather than resolving concrete tool behavior by protocol name. `TermindToolPresentationProfiles.renderer` composes knowledge, SSH, pane, and chat profiles with localized vocabulary; profiles control summaries, phases, pending detail, approval projection requirements, and truncation notices. Rendering leaves execution, approval, and replay payloads unchanged. An unknown or absent presenter ID does not recover SSH semantics from a matching tool name.
- **Privacy suppression is distinct from generic fallback.** Profile detail can return `.useDefault`, `.content`, or `.hidden`; hidden output must not leak through raw JSON or error rendering. Local pane/chat privacy profiles apply by name independently of presenter availability, not as semantic presenter recovery. MCP profiles preserve unprojected JSON and cannot select local presenter code through remote metadata. A presenter explicitly supplied by trusted calling code can still project an MCP card.
- **Tool-family policy is injected into a generic renderer.** `AgentToolPresentation` interprets descriptor metadata and lifecycle through an injected profile resolver and activity vocabulary, rather than resolving concrete tool behavior by protocol name. `TermindToolPresentationProfiles.renderer` composes knowledge, SSH, pane, and chat profiles with localized vocabulary; profiles control summaries, phases, pending detail, approval projection requirements, and truncation notices. Rendering leaves execution, approval, and replay payloads unchanged. Profile selection first returns an empty profile for an MCP target, then checks local pane/chat privacy policy, and otherwise looks up the explicit presenter ID. Unknown or absent IDs receive an empty profile, not SSH semantics recovered from a matching tool name; generic descriptor metadata can still drive the summary.
- **Privacy suppression is distinct from generic fallback.** Profile detail can return `.useDefault`, `.content`, or `.hidden`; hidden output stops before generic JSON or error rendering. Local pane/chat privacy profiles apply by name independently of presenter availability, not as semantic presenter recovery or executable registration. MCP receives an empty profile, not a raw-JSON-preservation policy, and cannot select local presenter code through remote metadata. After profile policy permits default detail, the renderer decodes result JSON: without a presenter it uses generic items (for example, `{"value":42}` becomes a `Value` field); an explicitly caller-supplied presenter can instead project the decoded result and supply its layout. Non-JSON output follows the generic text/error path. These are display choices, not changes to the stored or model-facing payload.
```mermaid
flowchart TD
Catalog["Remote catalog built-in and Termind presenters"] --> Apps["AppDependencies and MobileAppDependencies"]
Decorator["Presentation SSH result decorator"] --> Apps
Descriptor["Persisted tool descriptor"] --> Lookup["Reject MCP and require registered presenter ID"]
Descriptor["Persisted descriptor target and presenter ID"] --> Lookup["Reject MCP and require registered presenter ID"]
Apps --> Lookup
Lookup --> Presenter["Trusted decorated presenter or none"]
Profiles["Termind profiles and localized vocabulary"] --> Renderer["Generic AgentToolPresentation"]
Descriptor --> Profiles["Profile selection with localized vocabulary"]
Profiles --> MCP["MCP target gets empty profile"]
Profiles --> Local["Local pane and chat privacy first"]
Profiles --> ID["Otherwise explicit ID or empty profile"]
MCP --> Renderer["Generic AgentToolPresentation"]
Local --> Renderer
ID --> Renderer
Presenter --> Renderer
Card["Card metadata lifecycle and result"] --> Renderer
Renderer --> Native["Native transcript and approval views"]
Explicit["Explicit caller-supplied presenter"] --> Renderer
Card["Card lifecycle and result"] --> Renderer
Renderer --> Detail["Policy content or hidden or default detail"]
Detail --> Default["Default JSON uses presenter or generic items"]
Detail --> Native["Native transcript and approval views"]
Default --> Native
```
The apps compose trusted presenters across the remote/presentation boundary; injected profiles control rendering without changing executable registrations.
[`AgentToolPresentationProfileTests`](../../TFMTests/AgentToolPresentationProfileTests.swift) covers injected phase/detail/approval/truncation policies, custom vocabulary, ID-based profile selection, missing-ID fallback, and MCP isolation with explicit trusted projection.
[`AgentToolPresentationProfileTests`](../../TFMTests/AgentToolPresentationProfileTests.swift) covers injected phase/detail/approval/truncation policies and custom vocabulary. It verifies that an SSH profile follows its registered ID even after a tool rename, while unknown or absent IDs do not recover SSH behavior by name. Its MCP test supplies a local SSH presenter ID in remote metadata, verifies catalog lookup rejects it, and contrasts generic `Value` field rendering with an explicitly supplied presenter's `Projected` field and layout.
Pane integration is **optional capability injection**, not part of AgentKit's host-neutral catalog. `TermindAgentTools` constructs `list_panes` and `read_pane` only when `AgentPaneAccess` is supplied; absent access omits their executable definitions, while the presenter registry remains available for persisted cards. Similarly, host-facing scratch pull/push definitions require a supplied workspace. On mobile, `MobileSceneModel` supplies `app.paneAccess(for: self)` to its assistant scene model. The app adapter lists connected terminal workspaces with readable viewport surfaces and distinguishes closed, disconnected, and missing-surface reads; it derives active/current metadata from session and scene ownership. This keeps native terminal surfaces behind closures rather than importing UI into AgentKit or the tool catalog.
@@ -38,6 +38,10 @@ sources:
resource: repo://Frameworks/TermindPersistence/GRDBMemoryStore.swift
- id: openwiki-source-28d6772acb1a409d29ff1973
resource: repo://Frameworks/TermindPersistence/SwiftDataAgentRunRepository.swift
- id: openwiki-source-a575d2eb3628c3d9d4bd93bc
resource: repo://Frameworks/TermindPresentation/AgentChatToolPresentation.swift
- id: openwiki-source-743e6dcf5fbbd1fcc58c991e
resource: repo://Frameworks/TermindPresentation/AgentPaneToolPresentation.swift
- id: openwiki-source-3476c075c0a89fef4b1cecf4
resource: repo://Frameworks/TermindPresentation/AgentToolDetailPreview.swift
- id: openwiki-source-5b42af91dbdc738123786a99
@@ -46,6 +50,8 @@ sources:
resource: repo://Frameworks/TermindPresentation/AssistantMessageBody.swift
- id: openwiki-source-718a8dd6b4c7481c367a98e1
resource: repo://Frameworks/TermindPresentation/TermindMarkdownParser.swift
- id: openwiki-source-6ab30745153a4cbf15c4b18c
resource: repo://Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift
- id: openwiki-source-ee4e94c8b189e0881ec4fd15
resource: repo://Frameworks/TermindRemoteInfrastructure/Agent/AgentBackgroundCommands.swift
- id: openwiki-source-1fc00d0407016efa5a0378eb
@@ -122,16 +128,18 @@ sources:
resource: repo://TFMTests/AgentScratchTests.swift
- id: openwiki-source-7e117096f381ecc32caff068
resource: repo://TFMTests/AgentSkillTests.swift
- id: openwiki-source-7c65a9e84644dfdb436d849d
resource: repo://TFMTests/AgentToolPresentationProfileTests.swift
- id: openwiki-source-78797a18dd3153d23a2c42e2
resource: repo://TFMTests/ChatComposerStateTests.swift
- id: openwiki-source-32734a5d0c7e053627a24d40
resource: repo://TFMTests/ContextAttachmentImporterTests.swift
- id: openwiki-source-5a540932657f4174b82cb1eb
resource: repo://TFMTests/TerminalSuggestToolTests.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Agent Runtime and Assistant
@@ -415,7 +423,11 @@ A saved context snapshot preserves historical session, skill-catalog text, plan
Persisted text, tool arguments, titles and reasoning go through redaction. In particular, secret handles are replaced with expired lifecycle content on restore, and sensitive header values are redacted. **Original attachment bytes are a different storage boundary:** `PersistentAgentContextAttachments` encodes the captured attachments directly, without passing their bytes through `AgentPersistenceRedactor`. Do not assume that redaction of extracted prompt text sanitizes the original document retained for reopening.
Tool cards resolve an explicit persisted presenter ID through the immutable presenter registry, combining AgentKit built-in presenters with Termind registrations. `TermindAgentTools.presenter(for:)` refuses MCP descriptors and descriptors without a presenter ID; a bare historical tool name does not select executable presenter code. Termind no longer registers compatibility presenters for `builtin.ssh_exec` or `builtin.ssh_wait`; missing presenters follow the presentation profile's fallback policy. Registration and surface-availability changes preserve those identities and the persisted context key; they do not require a SwiftData schema change. Presentation is a separate projection: localized action verbs, punctuation and lifecycle summaries do not rewrite the original call or result used for execution, approval or replay. Built-in JSON results can use a registered structured presenter or a generic fallback, while MCP keeps remote-defined JSON output and does not use local presenters. Local chat-collaboration tools are an exception to generic fallback: missing/malformed or failed details produce a safe unavailable-details message, and approval arguments require their presenter rather than exposing a generic argument dump. Tool summaries group by tool, state and knowledge action so mixed successes and failures do not read as one success. `AgentToolDetailPreview` applies one whole-card body budget of five rows and `AgentTruncateLimits.maximumBytes`, following the presenter's truncation strategy rather than always using middle truncation. Fields, notices and non-collapsible text are outside that body budget; `.none` bypasses shortening. Full projected items and `fullText` remain available for expansion and Copy. This UI preview is distinct from runtime output projection: the controller also configures `AgentToolOutputProjection` with the shared scratch workspace. Both platforms use shared `AssistantMessageBody` over MarkdownView, and `TermindMarkdownParser` delegates block parsing to MarkdownParser. Inline titles retain emphasis, code, link destinations and image alt text; the previous soft-break rewriting and local unsafe-link filtering adapters were removed. Native list ownership, row measurement and interaction remain platform-owned.
Tool cards resolve an explicit persisted presenter ID through the immutable presenter registry, combining AgentKit built-in presenters with Termind registrations. `TermindAgentTools.presenter(for:)` refuses MCP descriptors and descriptors without a presenter ID; a bare historical tool name does not select executable presenter code. Termind no longer registers compatibility presenters for `builtin.ssh_exec` or `builtin.ssh_wait`; missing presenters follow the presentation profile's fallback policy. Registration and surface-availability changes preserve those identities and the persisted context key; they do not require a SwiftData schema change. Presentation is a separate projection: localized action verbs, punctuation and lifecycle summaries do not rewrite the original call or result used for execution, approval or replay.
Built-in JSON results can use a registered structured presenter or a generic fallback. **MCP descriptor lookup is not presenter injection:** remote descriptors cannot resolve local executable presenters, even if they advertise a local presenter ID. `TermindToolPresentationProfiles` gives MCP descriptors an empty profile, which permits generic structured detail fallback (for example, `{"value":42}` becomes a `Value` field), rather than requiring raw remote JSON display. A trusted caller can explicitly pass a presenter to `AgentToolPresentation.detail(for:presenter:locale:)`; the renderer uses that presenter's projection and layout even for an MCP card. Local pane and chat privacy profiles are selected independently of presenter availability, including by local tool name when presenter metadata is missing or unknown; this suppresses private fallback content, not recovery of executable presenter identity. Local chat-collaboration tools require presenter-projected approval arguments and use safe unavailable-details fallback for missing/malformed or failed detail data rather than exposing chat bodies; pane details remain metadata-only. These display policies do not alter replay payloads. See [UI Design Principles](ui-design-principles.md) for presentation policy and [System Boundaries](../architecture/system-boundaries.md) for the trust boundary. `TFMTests/AgentToolPresentationProfileTests.swift` verifies rejected MCP descriptor lookup, explicit presenter injection and layout, generic structured fallback, and ID-based profiles without tool-name recovery.
Tool summaries group by tool, state and knowledge action so mixed successes and failures do not read as one success. `AgentToolDetailPreview` applies one whole-card body budget of five rows and `AgentTruncateLimits.maximumBytes`, following the presenter's truncation strategy rather than always using middle truncation. Fields, notices and non-collapsible text are outside that body budget; `.none` bypasses shortening. Full projected items and `fullText` remain available for expansion and Copy. This UI preview is distinct from runtime output projection: the controller also configures `AgentToolOutputProjection` with the shared scratch workspace. Both platforms use shared `AssistantMessageBody` over MarkdownView, and `TermindMarkdownParser` delegates block parsing to MarkdownParser. Inline titles retain emphasis, code, link destinations and image alt text; the previous soft-break rewriting and local unsafe-link filtering adapters were removed. Native list ownership, row measurement and interaction remain platform-owned.
Compaction changes the **model-facing** transcript, not the scrollable display history. Its summary record is persisted before the live conversation applies it; after recovery the model receives a synthetic compaction summary plus recent messages while the user can still read the full original conversation.
+1 -1
View File
@@ -9,4 +9,4 @@
- [Shell Integration and Terminal Context](shell-integration.md) - SSH shell startup, multiplexer context inspection, display-only native directories, context-bound history and capability-gated drafts. Explains active-context authority, replay protection, command notifications and separate Telnet semantics.
- [SSH Multiplexing and Scheduling](ssh-multiplexing-and-scheduling.md) - The concrete ownership and scheduling layers behind Termind SSH: per-connection session leases, serial libssh2 workers, exec state machines, multiplexed SFTP retries, readiness, backpressure, and feature-specific connection reuse.
- [SSH Security-Key Authentication](ssh-security-key-authentication.md) - How Termind registers an RP-bound FIDO2/WebAuthn Security Key, stores its public reference, and turns a local authenticator assertion into an OpenSSH SSH signature across macOS and iOS.
- [UI Design and Presentation Contracts](ui-design-principles.md) - Shared presentation contracts and platform-specific layout, action, artwork, editor, settings, and terminal rules for consistent UI changes, with focused rendering and continuity tests.
- [UI Design Principles](ui-design-principles.md) - Shared presentation contracts and platform-specific layout, action, artwork, editor, settings, and terminal rules for consistent UI changes, with focused rendering and continuity tests.
+27 -6
View File
@@ -4,8 +4,6 @@ title: Persistence, Compatibility and Secrets
description: How Termind owns SwiftData and GRDB durable data, evolves compatible schemas, projects records through repositories, and keeps credentials in Keychain-backed and runtime-only boundaries.
tags: [persistence, swiftdata, grdb, migrations, keychain, secrets, security]
sources:
- id: openwiki-source-77c7271bd4dc81edee52ffc7
resource: repo://.build/fastlane-screenshots/mac/SourcePackages/checkouts/AgentKit/Sources/AgentKit/Security/AgentSensitiveDataRedactor.swift
- id: openwiki-source-685b7f8e7dbcf91b4e2a50e2
resource: repo://Frameworks/TermindApplication/Agent/AssistantConversationOperations.swift
- id: openwiki-source-5f99e8af445e073ffe9bc257
@@ -50,6 +48,8 @@ sources:
resource: repo://Frameworks/TermindInfrastructure/Cloud/CloudSyncLifecycle.swift
- id: openwiki-source-8a511ce5c3a76863609a6e6e
resource: repo://Frameworks/TermindInfrastructure/Cloud/CloudSyncLifecycleSafety.swift
- id: openwiki-source-8a2e7d4db4b334995f8eaf61
resource: repo://Frameworks/TermindPersistence/AgentPersistence.swift
- id: openwiki-source-85b30c7ff8f6f034b2bc980f
resource: repo://Frameworks/TermindPersistence/AgentPersistenceRedactor.swift
- id: openwiki-source-ec0a64adad50721ec500ebc2
@@ -142,6 +142,8 @@ sources:
resource: repo://FrameworkTests/TerminalTransportTests.swift
- id: openwiki-source-eaed8c88a9a3f24e3feb1f9c
resource: repo://FrameworkTests/WebAuthnVaultMetadataTests.swift
- id: openwiki-source-105d05d558f14996921a83f6
resource: repo://Termind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved
- id: openwiki-source-906678adb91c2fce2d3fcaed
resource: repo://TFI/App/MobileAppModel.swift
- id: openwiki-source-5b8c72c5373a41af34fa9fd4
@@ -172,10 +174,10 @@ sources:
resource: repo://TFMTests/AgentPersistenceTests.swift
- id: openwiki-source-1d1efb20e239b1f2142f6cb7
resource: repo://TFMTests/SettingsSyncTests.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Persistence, Compatibility and Secrets
@@ -235,7 +237,26 @@ Replay is backing for the original turn, not a fresh reconstruction from current
This backing is additive: historical message schemas remain frozen, and missing legacy context is not reconstructed from today's configuration. `AgentReplayPersistenceTests.v15MigratesWithoutInventingHistoricalContext` opens a V15 disk store through the production factory and verifies the legacy message survives with no context snapshot or invented replay row.
The inspectable app-side replay contract is explicit about ordering. [`AgentPersistenceRedactor.toolResultText`](../../Frameworks/TermindPersistence/AgentPersistenceRedactor.swift) first calls `AgentSecretLifecycle.persistedResultText`, then delegates to `AgentSensitiveDataRedactor.toolResultText`; lifecycle expiry must precede redaction so durable output does not retain runtime handles. The resolved-package snapshot's [`AgentSecretLifecycle`](../../.build/fastlane-screenshots/mac/SourcePackages/checkouts/AgentKit/Sources/AgentKit/Security/AgentSensitiveDataRedactor.swift) replaces `request_user_secret` output with an expired, single-use status envelope. That snapshot does **not** contain the `toolResultText` redactor API used by the current app, so it is not evidence for that API's structural-redaction, framing or sizing internals. Those remain a package contract, not an independently verified implementation here. On restore, the app wrapper repairs malformed JSON-looking or wrapped legacy text only by selecting a valid structured fallback from durable result content or frozen model content; without one, it retains the original text rather than guessing. Tool-role frozen `modelText` uses the same tool-result path; other roles use visible-text redaction.
The inspectable app-side replay contract is explicit about ordering. [`AgentPersistenceRedactor.toolResultText`](../../Frameworks/TermindPersistence/AgentPersistenceRedactor.swift) first calls `AgentSecretLifecycle.persistedResultText`, then delegates to `AgentSensitiveDataRedactor.toolResultText`; the wrapper deliberately applies lifecycle policy before structural redaction. [`PersistentAgentToolResult`](../../Frameworks/TermindPersistence/AgentPersistence.swift) uses this wrapper for durable result content. Tool-role frozen `modelText` in [`PersistentAgentMessageReplay`](../../Frameworks/TermindPersistence/PersistentAgentMessageReplay.swift) uses the same path; other roles use visible-text redaction.
On restore, the wrapper considers repair only when trimmed text starts with the untrusted-data opening marker, `{`, or `[` and structured decoding fails. It selects the first fallback that decodes as structured data; otherwise it retains the original text, including ordinary plain output, rather than guessing. [`SwiftDataAgentRunRepository`](../../Frameworks/TermindPersistence/SwiftDataAgentRunRepository.swift) repairs frozen tool model text from durable result model content, then repairs transcript text from durable result content or the recovered model text. The durable result's own restore path can recover from its frozen model content.
```mermaid
flowchart TD
ResultText["Tool result text or tool-role frozen model text"] --> Lifecycle["Apply AgentSecretLifecycle persistence policy"]
Lifecycle --> Redactor["Delegate to AgentSensitiveDataRedactor"]
Redactor --> Stored["Persist app-owned backing"]
Stored --> Restore["Restore tool text"]
Restore --> Malformed{"Structured-looking text fails decoding"}
Malformed -->|no| Keep["Keep original text"]
Malformed -->|yes| Fallback{"Valid structured fallback available"}
Fallback -->|yes| Recover["Select first valid fallback"]
Fallback -->|no| Keep
```
The app orders lifecycle policy before redaction and repairs legacy text only from decodable structured backing.
**Observable contract and evidence limit.** [`AgentReplayPersistenceTests`](../../FrameworkTests/AgentReplayPersistenceTests.swift) defines a `request_user_secret` persistence fixture that requires decodable output with `handle_status` equal to `expired`, no `secret_handle` field, and no original handle string. Its parameterized crash-recovery fixture requires malformed wrapped JSON to recover the frozen structured preview while plain output stays unchanged; both retain the frozen model preview and error flag. These are app-facing assertions, not an inspection of AgentKit's implementation or a report of tests executed here. The checked-in [`Package.resolved`](../../Termind.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved) identifies AgentKit 4.0.0 at revision `3481866cd47e83f6bf56b80c432c7824f61130b9` from `https://github.com/AkinoKaede/AgentKit.git`. That pin establishes dependency identity only: it does not prove internal redaction algorithms, envelope construction, or size limits. No dependency checkout or build-cache source is needed for the app-side ordering and recovery contracts above.
Restore and truncation share a canonical ordering: runs by `startedAt` then UUID; messages by that run order, then `sequence`, `createdAt`, role rank and UUID. Timestamps alone do not identify the cutoff. `truncateConversation` checks cancellation and validates an ordinary user replacement with a fresh ID that collides with neither a stored message nor a run before mutation. It removes the selected user message and the ordered suffix, including whole later runs. When the target run still has a prefix, that run and its retained messages survive: the summary becomes neutral `.completed`, clears its previous failure and ends at the last retained non-tool message. Editing its opening removes the target run only when no prefix remains.
+39 -13
View File
@@ -1,6 +1,6 @@
---
type: design guide
title: UI Design and Presentation Contracts
title: UI Design Principles
description: Shared presentation contracts and platform-specific layout, action, artwork, editor, settings, and terminal rules for consistent UI changes, with focused rendering and continuity tests.
tags: [ui, design-system, presentation, accessibility, localization, macos, ios]
sources:
@@ -22,8 +22,8 @@ sources:
resource: repo://Frameworks/TermindPresentation/AgentPaneToolPresentation.swift
- id: openwiki-source-5b42af91dbdc738123786a99
resource: repo://Frameworks/TermindPresentation/AgentToolPresentation.swift
- id: openwiki-source-7e27e66540bd1ea5c642a652
resource: repo://Frameworks/TermindPresentation/AgentToolPresentationProfile.swift
- id: openwiki-source-ea5e06cbcadf0b0308e859c6
resource: repo://Frameworks/TermindPresentation/AssistantToolDetails.swift
- id: openwiki-source-400e4d9303a3f9d98f90660d
resource: repo://Frameworks/TermindPresentation/AssistantTranscriptEntry.swift
- id: openwiki-source-eec1a2bc6dfc2c60b2bee55c
@@ -168,6 +168,8 @@ sources:
resource: repo://TFMTests/AgentKnowledgeToolPresentationTests.swift
- id: openwiki-source-7c65a9e84644dfdb436d849d
resource: repo://TFMTests/AgentToolPresentationProfileTests.swift
- id: openwiki-source-23ab3fe73660b171f78763a4
resource: repo://TFMTests/AgentToolPresentationTests.swift
- id: openwiki-source-d3d065330c730839f5cc6112
resource: repo://TFMTests/ArchitectureBoundaryTests.swift
- id: openwiki-source-dc392b9979d99f5026bdeadf
@@ -188,13 +190,13 @@ sources:
resource: repo://TFMTests/WorkspaceLayoutDropTests.swift
- id: openwiki-source-a3093a0c1d98ecc1cdbc0279
resource: repo://TFMTests/WorkspaceNavigatorDropTests.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# UI Design and Presentation Contracts
# UI Design Principles
Termind shares the *meaning* of actions, copy, form fragments and display values, not a cross-platform view tree. TFM owns window routing, persistent workspace views and pointer/keyboard controls; TFI owns scene destinations, native navigation stacks and touch-oriented sheets. See [Desktop UI](../architecture/desktop-ui.md), [Mobile UI](../architecture/mobile-ui.md), and [Commerce and Localization](commerce-localization-and-product-surfaces.md) for the surrounding ownership boundaries.
@@ -343,7 +345,7 @@ Selection is a persisted user action; a missing stored theme is a display-time f
`AgentToolPresentation` is a generic projection of descriptor metadata and lifecycle state, not an execution or replay owner. The app uses `TermindToolPresentationProfiles.renderer` to inject tool-family policies and localized vocabulary. Profiles can override summary, operation, batch operation, phase wording, detail and truncation notices. Detail decisions distinguish `.hidden` from `.useDefault`: suppression must not accidentally enter a generic JSON/error fallback.
The trusted composition selects registered profiles by `presenterID`; unknown IDs do not recover executable presentation code from a similar tool name. Local pane/chat privacy policies are applied independently of presenter availability. MCP descriptors cannot select local code: without an explicitly supplied presenter they retain JSON presentation; a caller-supplied MCP presenter can project typed details.
The trusted composition selects registered profiles by `presenterID`; unknown IDs do not recover executable presentation code from a similar tool name. Local pane/chat privacy policies are applied independently of presenter availability. MCP descriptors receive the default profile, not local tool-family policy. Without a trusted, explicitly supplied presenter, decoded MCP JSON uses the same **generic structured fields** as an unregistered local tool—not a forced raw JSON block, even with `output: .json`. For example, `{"value":42}` becomes a `Value` field containing `42`. An explicit presenter can instead emit its own typed items and layout. Remote metadata cannot select local executable presentation code; presenter injection is a separate trusted caller decision. See [System Boundaries](../architecture/system-boundaries.md).
Live approval projects the **in-memory request**, not durable-card or model-transcript arguments. Ordinary arguments remain reviewable without redaction; resolved Host names allow hiding redundant `host_id`. Sensitive chat tools require argument projection and return no argument items when the presenter is unavailable, rather than exposing raw prompt/message fields. Short approval titles keep argument bodies in the detail area.
@@ -358,16 +360,40 @@ flowchart TD
Renderer --> Policy{Profile detail decision}
Policy -->|hidden| Hidden[No detail]
Policy -->|content| Typed[Typed detail]
Policy -->|useDefault| Fallback[JSON decoding and presenter or generic fallback]
Fallback --> Typed
Typed --> Preview[Compact and full native disclosure]
Approval --> Review[User-only review surface]
Policy -->|useDefault| Decode[Decode result JSON]
Decode -->|Trusted explicit presenter| Project[Project typed items with failure state]
Decode -->|No presenter| Generic[Generic structured items]
Decode -->|Invalid JSON| Message[Output message or suppressed duplicate denial]
Project --> Typed
Generic --> Typed
Message --> Typed
Typed --> Preview[Compact preview or full retained items]
Approval --> Review[Always-visible arguments]
Request --> Safety[Separate safety-reasons disclosure]
```
The presentation branches consume execution data without rewriting the original call/result or attaching live approval details to persistence or model transcripts.
Failed, denied or interrupted ordinary JSON results pass failure state to registered presenters; knowledge-tool regressions ensure failures cannot draw success messages. Matching Guardian denial text is suppressed in result detail to avoid printing the same reason twice. Chat failure/malformed/missing-presenter paths use bounded unavailable-details feedback, not raw bodies. Local `read_pane` shows only terminal name and pane ID (with argument-ID fallback), including malformed/error results; it never reaches raw-output fallback and hides truncation notices. `list_panes` renders terminal rows with active/current badges.
`AgentToolDetailPreview` retains full typed items while providing compact items. Desktop Show More/Show Less disclosure is keyed by tool-card ID, and native detail labels remain selectable. Extend profiles and registered projectors rather than changing protocol payloads. `AgentToolPresentationProfileTests` checks injected overrides, explicit MCP presenters and unknown-ID isolation; `AgentKnowledgeToolPresentationTests` checks approval bodies, failure-safe details, title limits without argument mutation, preview budgets and independent disclosure.
`AgentToolDetailPreview` retains full typed items while providing compact items. Desktop Show More/Show Less disclosure is keyed by tool-card ID, and native detail values remain selectable. Extend profiles and registered projectors rather than changing protocol payloads. `AgentToolPresentationProfileTests` checks injected overrides, explicit MCP presenters and unknown-ID isolation; `AgentKnowledgeToolPresentationTests` checks approval bodies, failure-safe details, title limits without argument mutation, preview budgets and independent disclosure.
### Retained detail rendering and approval visibility
`AssistantToolDetails` renders the supplied items verbatim: it does not perform a second truncation or insert per-item folding. `AssistantCompactToolDetails` chooses `preview.items` or `preview.fullItems` using a transcript-owned expansion binding; the desktop native compact renderer makes the same choice using `.toolDetail(card.id)`. Full here means the retained **projected** items, not recovery of raw private payloads. The preview shares a five-row/body-byte budget across collapsible bodies and lists, while fields, messages and noncollapsible text remain outside that body budget.
| Contract | Shared SwiftUI `AssistantToolDetails` | Desktop native transcript |
| --- | --- | --- |
| Field layout | Leading vertical stack: secondary medium caption label above the value, four-point spacing | Vertical stack with secondary medium small-font label above the value |
| Empty field value | Keeps the label and omits the value view | Returns the label alone |
| Navigation and URLs | Trusted navigation button takes precedence when `assistantToolNavigation` is installed; otherwise a parseable URL becomes a `Link`, then plain text | Chat reference takes precedence and calls `navigateChat`; otherwise a parseable URL opens through `NSWorkspace`, then plain text |
| Typography and selection | Monospaced flag applies to text/navigation values; URL links use caption font. The container enables text selection | Monospaced flag applies to plain and button values; plain values, messages and text blocks explicitly enable selection |
| Error styling | Plain field values and text blocks turn red with `isError`; labels stay secondary, links retain link styling, messages use their explicit tint | Same role distinction using native colors; the compact caller supplies `card.result?.isError == true` |
These are matching semantic roles, not pixel or interaction parity: SwiftUI text blocks use a horizontal scroll view, and links/buttons are actions rather than ordinary selectable text. Keep navigation in app-owned handlers rather than interpreting field strings as local routes.
`AssistantApprovalDetails` renders all `detail.items` directly with primary body text. Only the safety reasons are inside the separate `showsSafetyDetails` disclosure; collapsing safety must not hide the arguments being approved. This visibility rule is distinct from durable persistence redaction and from the sensitive-chat projection policy above.
Focused verification: `builtInAndMCPFallbackUseTheSameFields` asserts equal generic structured items, and `explicitMCPPresenterIsUsedButRemoteMetadataCannotSelectLocalCode` distinguishes the generic `Value` field from an explicit `Projected` field and presenter layout. Approval tests retain an unredacted command/token and generic password argument; knowledge tests preserve complete long approval bodies and full preview items. These tests verify projection and disclosure state, not SwiftUI/AppKit pixel parity. The renderer comparison above is source inspection; rendering suites were not executed for this update.
Sources: [generic renderer](../../Frameworks/TermindPresentation/AgentToolPresentation.swift), [profile contract](../../Frameworks/TermindPresentation/AgentToolPresentationProfile.swift), [trusted composition](../../Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift), [pane privacy](../../Frameworks/TermindPresentation/AgentPaneToolPresentation.swift), [chat privacy](../../Frameworks/TermindPresentation/AgentChatToolPresentation.swift).
+8 -10
View File
@@ -12,10 +12,6 @@ sources:
resource: repo://.gitmodules
- id: openwiki-source-8037e2358a2c4f9b2c722a11
resource: repo://AGENTS.md
- id: openwiki-source-6c477adbd17d240038ac8d60
resource: repo://com.akinokaede.termind/package.json
- id: openwiki-source-fcca55af6fa67b76822099ae
resource: repo://com.akinokaede.termind/README.md
- id: openwiki-source-7af97a29763d6f133e4b4851
resource: repo://fastlane/Fastfile
- id: openwiki-source-cf46ee9dde9e2af41c84b62f
@@ -66,10 +62,10 @@ sources:
resource: repo://TFMTests/Screenshots/MacScreenshotTests.swift
- id: openwiki-source-a08489338be00125d646c77e
resource: repo://TFMTests/VisibleWindowTestTrait.swift
generated: { by: "pi", at: "2026-10-19T04:32:02.799Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T04:32:02.799Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Build, Test, and Release
@@ -270,14 +266,16 @@ There is no local `AgentKit/` package or `AgentKit/Scripts/build-localizations.s
## Public website validation and asset publishing
Initialize `com.akinokaede.termind` only for website/asset work; native app builds do not require it. Its checked-out README requires Node.js 22.12 or newer. The manifest defines `dev` as `astro dev` and `build` as `astro check && astro build`; run `npm run test:locales` after the build for the site's documented locale, metadata, link and asset checks.
Initialize `com.akinokaede.termind` only for website/asset work; native app builds do not require it. [AGENTS.md](../../AGENTS.md) identifies it as an independent Astro project and supplies the optional workflow: `npm ci && npm run dev` installs locked dependencies and starts local development, while `npm run build` type-checks and emits the production site. [.gitmodules](../../.gitmodules) declares the submodule path and public clone URL, `https://github.com/AkinoKaede/com.akinokaede.termind.git`.
```sh
git submodule update --init com.akinokaede.termind
(cd com.akinokaede.termind && npm ci && npm run build && npm run test:locales)
(cd com.akinokaede.termind && npm ci && npm run build)
```
The parent repository's `AGENTS.md` requires the separate production build and visual review of English and `/zh/`. The site's current guidance documents `/`, `/de/`, `/fr/`, `/ja/`, `/ko/`, `/zh-hans/`, and `/zh-hant/`, with legacy `/zh/` redirects to Simplified Chinese. Review the affected localized routes as well as the legacy redirect; the parent guidance is not a complete route inventory. Generated `dist/`, `.astro/` and `node_modules/` stay uncommitted. Commit/push reviewed assets via SSH first, then update the parent gitlink; retain the public HTTPS clone URL in `.gitmodules`.
The website directory is empty in this checkout; its README and package manifest were not available for inspection. After initialization, verify the independent project's Node.js requirement, actual package scripts, and any additional locale checks in its own current guidance before running them. The commands above are parent-repository instructions, not verified website manifest contents.
[AGENTS.md](../../AGENTS.md) requires a production build and visual review of English and `/zh/` for web changes. Verify the initialized site's current locale routes and redirect behavior before choosing additional review coverage; this checkout does not establish a route inventory or legacy redirect contract. Keep generated website output and dependencies uncommitted. Parent guidance also requires committing and pushing reviewed assets via SSH before updating the parent gitlink, while retaining the public HTTPS clone URL in `.gitmodules`.
## AgentKit: release, bump, and re-resolve
@@ -8,10 +8,6 @@ sources:
resource: repo://.gitmodules
- id: openwiki-source-8037e2358a2c4f9b2c722a11
resource: repo://AGENTS.md
- id: openwiki-source-54a517e25bf7220eb9067177
resource: repo://com.akinokaede.termind/assets/README.md
- id: openwiki-source-0246c48ce8a82949613e5d20
resource: repo://com.akinokaede.termind/design/README.md
- id: openwiki-source-cdbd4afdca339b59b83eee2e
resource: repo://Configuration/HostIcons/linux-distribution-icons.json
- id: openwiki-source-7af97a29763d6f133e4b4851
@@ -74,17 +70,17 @@ sources:
resource: repo://TFMTests/Screenshots/MacScreenshotTests.swift
- id: openwiki-source-7185b2e5254dcfff2e6ac796
resource: repo://TFMTests/Screenshots/ScreenshotDemoTests.swift
generated: { by: "openwiki/0.7.2", at: "2026-10-19T03:39:12.674Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T03:39:12.674Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Marketing Assets and App Icons
This is the operational home for Termind's asset workflow. Capture tooling and native fixtures belong to the application repository; `AGENTS.md` assigns the public website and marketing/brand assets to the independent `com.akinokaede.termind` submodule. Native builds do not require that checkout.
**Verification boundary:** this guide follows the `fd88d6` tooling baseline. The available website/assets checkout is initialized; its READMEs identify asset and design responsibilities. Dimensions below are primarily parent tooling contracts, not a fresh visual audit of external files. No focus-taking captures, generator downloads or visual artwork approval were performed for this documentation repair.
**Verification boundary:** the available `com.akinokaede.termind/` checkout is empty, so external READMEs, images, design masters and delivery contracts could not be inspected. Dimensions below are parent tooling contracts, not an audit of external files. Initialize the submodule before checking its inventory or publication instructions. No focus-taking captures, generator downloads or visual artwork approval were performed for this documentation repair.
The former MockUPhone pipeline, feature-first `Marketing/` layout, `LandingPage/` project and Pro Max captures are obsolete. The current pipeline uses **fastlane `run_tests` (scan)** with hosted Swift Testing fixtures, **frameit** plus local Apple templates, locale/device-first asset paths, iPhone 18 Pro and optional Duo displays, and native 14-inch Mac Workspace captures. This is not XCUITest `snapshot` automation.
@@ -310,7 +306,7 @@ The mask algorithm expects transparency both outside the device and inside its d
## External composition, website and store delivery
`AGENTS.md` identifies the submodule root as an independent Astro project and documents `npm run build` as type-checking and emitting `dist/`. The initialized checkout's [README](../../com.akinokaede.termind/README.md) is the entrypoint for website development and publication; its [asset guide](../../com.akinokaede.termind/assets/README.md) distinguishes final `screenshots/`, `header/` and `search_results/` artwork from captures and frames. These documents do not substitute for inspecting image pixels, current consumers or deployed settings.
[AGENTS.md](../../AGENTS.md) identifies the submodule root as an independent Astro project and documents `npm run build` as type-checking and emitting `dist/`. Its website, asset and design documentation is unavailable in this checkout. After initialization, locate and read the current instructions for development, composition and publication; do not infer final artwork directories or delivery contracts from the parent runner's capture and frame paths.
Before publishing, initialize and inspect the external repository separately:
@@ -324,7 +320,7 @@ This page makes no current claim about a 96-board inventory, Overview filenames,
## Brand, layered app icons and Pro handoff
External brand masters and website variants belong to the submodule. Its design README identifies `brand/termind.svg` as the master and `public/brand_mark.svg` / `public/favicon.svg` as website variants. Inspect the actual SVGs before editing; README guidance is not visual approval.
External marketing and brand assets belong to the submodule under `assets/` and `design/`, according to `AGENTS.md`. After initialization, identify the authoritative brand master and website variants from current documentation and actual SVG consumers. Their filenames and contents are not verified here; inspect them before editing or approving exports.
Platform `AppIcon.icon` documents remain app-owned and selected as `AppIcon` by Xcode. Their SVG groups are Terminal, FrontWindow, MiddleWindow, BackWindow; preserve order, shared-square platform declaration, lighting, disabled glass/specular/translucency, no Terminal shadow and the subtle 0.08 neutral window shadows. Icon Composer/Xcode own platform padding, masks and compatibility renditions. Do not introduce another flattened appiconset or manually generated size matrix. Build both platform sources with pinned dependencies; TestFlight processing is a separate release check, and a temporary macOS bundle identifier can bypass local icon cache during manual review.
@@ -339,7 +335,7 @@ A separate website rendition can be exported from the Mac source to an initializ
Shared `Frameworks/Resources/Assets.xcassets` owns runtime AccentColor and vector/template host artwork, separately from marketing frames and compiled app icons. See the host-artwork workflow below.
Paywall illustrations are externally owned under `com.akinokaede.termind/design/paywall/`; follow the checkout's [design guidance](../../com.akinokaede.termind/design/README.md). The former `Scripts/render-pro-paywall-icon.swift` renderer is absent: there is no current parent generation command or guaranteed 80×72-point export contract. Native `ProPaywallView` / `MobileProView` embed `RevenueCatUI.PaywallView` when using RevenueCat. Editing handoff artwork does not publish a remote paywall; review and upload through the commerce workflow intentionally.
Locate any paywall illustration sources and handoff instructions only after initializing and inspecting the external checkout; no `design/paywall/` inventory or export contract is verified here. The former `Scripts/render-pro-paywall-icon.swift` renderer is absent: there is no current parent generation command or guaranteed 80×72-point export contract. Native `ProPaywallView` / `MobileProView` embed `RevenueCatUI.PaywallView` when using RevenueCat, rather than loading illustrations from the external checkout. Editing handoff artwork does not publish a remote paywall; review and upload through the [storefront commerce release workflow](storefront-commerce-release.md) intentionally.
The former `MobileIconRenderingTests` suite is also absent. Use the current `MobileScreenshotTests` capture fixture for supported product scenes, and Icon Composer/Xcode for app-icon review; neither is a replacement claim of automated icon-label coverage.
@@ -130,8 +130,8 @@ sources:
resource: repo://TFMTests/AgentHostAuthenticationTests.swift
- id: openwiki-source-715de8d16be5a3d06ae915ad
resource: repo://TFMTests/AgentPersistenceTests.swift
- id: openwiki-source-23ab3fe73660b171f78763a4
resource: repo://TFMTests/AgentToolPresentationTests.swift
- id: openwiki-source-7c65a9e84644dfdb436d849d
resource: repo://TFMTests/AgentToolPresentationProfileTests.swift
- id: openwiki-source-d3d065330c730839f5cc6112
resource: repo://TFMTests/ArchitectureBoundaryTests.swift
- id: openwiki-source-78797a18dd3153d23a2c42e2
@@ -164,10 +164,10 @@ sources:
resource: repo://TFMTests/WindowToolbarFindTests.swift
- id: openwiki-source-d798805795e92534f3b13250
resource: repo://TFMTests/WorkspaceCloseConfirmationTests.swift
generated: { by: "pi", at: "2026-10-19T04:32:02.799Z" }
generated: { by: "openwiki/0.7.0", at: "2026-10-19T23:15:37.894Z" }
verified:
- by: openwiki/0.7.2
at: 2026-10-19T04:32:02.799Z
- by: openwiki/0.7.0
at: 2026-10-19T23:15:37.894Z
---
# Behavioral Boundaries and Test Fixtures
@@ -343,8 +343,34 @@ SFTP transfer tests use a controlled `TransferChannelHarness`, a `TransferChanne
Those tests are intentionally actor-driven and use polling only to wait for observable harness state. Prefer this style for races: hold the transfer at a known point, make the ownership transition, then release it and assert the terminal state and disconnect count.
### Tool presentation: projection authority is not remote metadata
For tool-card changes use `AgentToolPresentationTests`: the registered tool's argument projection appears in approval detail (including submitted command/input, not a claimed secret-redaction guarantee), while unknown tools get generic fields. Check the composed AgentKit-plus-Termind presenter ID catalog for collisions, restored cards for presenter-ID-directed detail and cards without presenter IDs for generic fallback (not equivalent detail), and old descriptor metadata for safe defaults before relying on a new presentation field. Batch and long-output fixtures cover mixed lifecycle states, Unicode preview bounds and full-copy content; avoid replacing structured detail with an untested JSON string.
Use the following focused assertions rather than treating “tool presentation” as one security or visual guarantee:
| Changed contract | Focused regression and asserted boundary |
| --- | --- |
| Trusted MCP projection versus remote-selected code | `AgentToolPresentationProfileTests.explicitMCPPresenterIsUsedButRemoteMetadataCannotSelectLocalCode` gives an MCP descriptor the SSH built-in ID and expects registry lookup to return `nil`. An explicitly supplied presenter still renders `Projected: 42` with its compact layout; without it the same payload renders generic `Value: 42`. Rejecting metadata-selected local code does **not** mean rejecting a trusted presenter passed by the caller. |
| Profile identity and extension hooks | `registeredProfileFollowsItsIDNotTheToolName` keeps “Connecting” for a renamed tool with the registered SSH ID, but an unknown ID or missing presentation yields generic summaries and no pending detail. `injectedProfileControlsPhasesPendingDetailsApprovalAndTruncation` separately checks injected phase text, pending content, hidden result detail, required argument projection and hidden truncation notices; the unconfigured renderer behaves differently. |
| Privacy when projection is unavailable | `missingChatApprovalPresenterNeverFallsBackToPromptOrMessageFields` expects empty approval items for local create/send chat without a presenter. `chatFallbacksNeverExposeMalformedErrorOrUnprojectedBodies` expects “Chat details unavailable” for malformed output, error output and a missing presenter. `chatCompactPreviewAndFullCopyContainOnlyProjectedBoundedFields` excludes message bodies and creator titles/IDs from both preview and full copy, while retaining the last projected chat in full copy. These are chat-specific suppression assertions, not a general redaction promise. |
| Knowledge summaries and approval content | `AgentKnowledgeToolPresentationTests` repairs old memory semantics across nine states in English and both Chinese variants, checks mode-specific actions and mixed read/write failures, rejects unknown/remote presenter selection, and prevents failed install results from drawing success messages. Its approval fixture keeps the body out of the title but includes the complete 1,000-line content in detail; title shortening leaves the original query unchanged. |
| Shared preview/state versus native detail layout | Knowledge tests preserve `fullItems`/full text while sharing the compact budget across blocks and five rows across lists. Detail expansion is independent of tool expansion, survives reconfiguration and is removed when its timeline ID is pruned. `TranscriptListViewBridgeTests.compactToolExpansionKeepsBothButtonTitlesLeftAligned` in `TranscriptListViewTests.swift` checks native “Show more” and “Show less” at widths 360 and 900, left alignment, the truncation notice before the button, and the final collapsed detail state. These are separate model and offscreen AppKit assertions, not cross-platform screenshot equivalence. |
The application composes profiles in [TermindToolPresentationProfiles](../../Frameworks/TermindPresentation/TermindToolPresentationProfiles.swift): MCP descriptors receive an empty profile; ordinary semantic selection uses `presenterID`. Local pane/chat privacy is deliberately selected independently of presenter availability, so do not remove that exception while eliminating tool-name-based semantic recovery. Approval visibility is a separate contract: the general fallback fixture explicitly displays `Password: hunter2`, and SSH approval displays the submitted command. The SSH control-result fixture instead excludes secret input and its opaque handle while retaining the command ID and formatted byte count.
Start with these non-window projection suites:
```sh
xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile test \
-only-testing:TFMTests/AgentToolPresentationTests \
-only-testing:TFMTests/AgentToolPresentationProfileTests \
-only-testing:TFMTests/AgentKnowledgeToolPresentationTests
```
For native expansion changes, additionally select the containing native-row suite in `TranscriptListViewTests.swift`; keep offscreen checks enabled normally. Tests that actually show windows or activate the app must retain `.requiresVisibleWindow` and require `TEST_RUNNER_TERMIND_WINDOW_TESTS=1` (host `TERMIND_WINDOW_TESTS=1`), with a narrow `-only-testing:TFMTests/<Suite>` filter. A default green run with gated cases skipped is not visible-window validation. See [UI Design Principles](../concepts/ui-design-principles.md) for rendering responsibilities and [Build, Test, and Release](../operations/build-test-and-release.md) for broader validation.
For Ghostty menu changes, `TFMTests/TerminalContextMenuTests.swift` checks AppKit blank-space and selection menus, Paste on Right Click/Option behavior, live upload availability and late pane teardown. `MobileTerminalUploadMenuTests` has been removed; do not claim current mobile editing/Upload/AutoFill ordering coverage from it. Add a focused regression for that contract when changing the mobile hooks; test removal alone is not evidence that the production menu behavior was removed.
Package gesture/selection validation remains a separate **upstream-package step**, not locally inspected or executed coverage here. Ghostty comes directly from `Lakr233/libghostty-spm`; there is no local maintenance submodule to initialize. Inspect the selected package's source/tests for direct-touch, indirect-pointer and dispatch behavior rather than assuming the removed fork's paths. Termind owns grouping/localization through separate `touchMenuItems(for:)` / `touchSelectionMenuItems(for:)` overrides; app composition tests do not establish package internals. See [Ghostty Terminal Integration](../concepts/ghostty-terminal-integration.md) and [Build, Test, and Release](../operations/build-test-and-release.md#ghostty-direct-upstream-dependency).