@@ -240,7 +240,7 @@ SIN-Code/
240240├── go.mod ← module github.com/OpenSIN-Code/SIN-Code
241241├── .goreleaser.yaml
242242├── .github/workflows/
243- │ ├── ceo-audit.yml ← n8n delegation (mandate M1)
243+ │ ├── ceo-audit.yml ← n8n delegation (mandate M1) + profile-verify job (issue #175)
244244│ ├── sin-code-release.yml ← goreleaser + brew tap
245245│ └── ecosystem-sync.yml ← prevents registry/permission/ECOSYSTEM drift
246246├── install.sh ← 27-line curl|bash shim → `sin-code install` (issue #170)
@@ -252,7 +252,9 @@ SIN-Code/
252252│ ├── HOOKS.md
253253│ ├── LEARNING.md
254254│ ├── WEBUI.md ← WebUI-v2 backend contract
255- │ └── mcp.json.example
255+ │ ├── mcp.json.example
256+ │ └── agent-profiles/
257+ │ └── sin-profile.md ← v3.18.0: single-source-of-truth per-agent profile (issue #175)
256258│
257259├── cmd/
258260│ ├── sin-code/ ← MAIN BINARY (40 subcommands — v3.18.0)
@@ -280,6 +282,10 @@ SIN-Code/
280282 │ │ ├── compress_cmd.go ← v3.18.0: sin-code compress subcommand (plan/apply/rollback, issue #172)
281283 │ │ ├── permission_defaults.go ← C4: default rules + MCP prefix policy
282284│ │ └── internal/ ← 17 packages (v3.8.0)
285+ │ │ ├── install_cmd.go ← v3.18.0: sin-code install (issue #170)
286+ │ │ ├── profile_cmd.go ← v3.18.0: single-source-of-truth profile renderer (issue #175)
287+ │ │ ├── permission_defaults.go ← C4: default rules + MCP prefix policy
288+ │ │ └── internal/ ← 18 packages (v3.18.0)
283289│ │ ├── agentloop/ ← PLAN→ACT→VERIFY→DONE loop
284290│ │ ├── session/ ← SQLite-backed resumable sessions
285291│ │ ├── permission/ ← allow/ask/deny engine
@@ -299,6 +305,8 @@ SIN-Code/
299305│ │ ├── summary/ ← v3.13.0: deterministic session summary builder
300306│ │ ├── install/ ← v3.18.0: pure-stdlib release install + SHA256 verify + atomic place (issue #170)
301307│ │ ├── mcpcompress/ ← v3.19.0: ponytail-tag compressor for `serve --compress-tools`
308+ │ │ ├── install/ ← v3.18.0: pure-stdlib release install + SHA256 verify (issue #170)
309+ │ │ ├── profile/ ← v3.18.0: single-source-of-truth per-agent renderer (issue #175)
302310│ │ ├── llm/ ← provider layer
303311│ │ ├── style/ ← v3.17.0: verbosity / compression mode system-prompt renderer (issue #167)
304312│ │ ├── orchestrator/ ← DAG, critic, adversary, governor, ...
@@ -518,6 +526,7 @@ Core: discover, execute, map, grasp, scout, harvest, orchestrate,
518526 ibd, poc, sckg, adw, oracle, efm
519527Agents: chat, sessions, mcp, goal, daemon, skill, superpowers,
520528 vane, stack, gh, install
529+ vane, stack, gh, install, profile
521530Frontend: serve, tui, webui
522531Lifecycle: memory, knowledge, todo, notifications, orchestrator_run,
523532 orchestrator_agents, orchestrator_plan, update
@@ -526,6 +535,42 @@ Utility: read, write, edit, lsp, plugin, index, security, sbom,
526535``` (v3.18.0: 40 subcommands; `install` is the v3.18.0 single-binary installer from issue #170)
527536 config, self-update, hub, ledger, summary, compress
528537``` (v3.18.0: 40 subcommands, up from 39 in v3.13.0)
538+ ``` (v3.18.0: 40 subcommands, up from 39 in v3.16.0;
539+ `install` is the v3.18.0 single-binary installer from issue #170;
540+ `profile` is the v3.18.0 single-source-of-truth per-agent renderer
541+ from issue #175.)
542+
543+ ### Per-agent profile distribution (issue #175)
544+
545+ `sin-code profile` renders the single in-repo source
546+ (`docs/agent-profiles/sin-profile.md`, ≤80 lines, KISS) into every
547+ per-host-agent mirror file. The render is **byte-stable** per
548+ `(target, source)` pair; the verify gate (`sin-code profile verify`)
549+ refuses to pass whenever any mirror drifts off the source SHA. Adding
550+ a target is non-breaking; renaming or removing one is a major bump.
551+ The single source of truth for the table is
552+ `cmd/sin-code/internal/profile/target.go` — keep the AGENTS.md row in
553+ sync if the table moves.
554+
555+ | Target | Format | Install path (relative to repo root) |
556+ | ------------- | ------- | ----------------------------------------------------------- |
557+ | claude-code | dir | `.claude/skills/sin-code/SKILL.md` |
558+ | opencode | dir | `.config/opencode/skills/sin-code/SKILL.md` |
559+ | gemini | dir | `.gemini/skills/sin-code/SKILL.md` |
560+ | codex | rule | `.codex/rules/sin-code.md` |
561+ | cursor | rule | `.cursor/rules/sin-code.mdc` |
562+ | windsurf | rule | `.windsurf/rules/sin-code.md` |
563+ | cline | rule | `.clinerules/sin-code.md` |
564+ | copilot | marker | `.github/copilot-instructions.md` |
565+
566+ The four marker-fence outputs (`rule` + `marker`) wrap the body in
567+ `<!-- SIN-CODE-SKILL-START: sin-code -->` … `<!-- SIN-CODE-SKILL-END: sin-code -->`
568+ inside the file. The fence is **byte-identical** to the one
569+ `internal/skilldist` uses (issue #169): the two systems share the
570+ same anchor (`SIN-CODE-SKILL`) so a downstream parser finds both
571+ per-skill bundles and per-profile mirrors with one regex. Profile
572+ renders are idempotent (rerun with unchanged source = byte-identical
573+ output), exactly as skilldist demands.
529574
530575### Hook events (verified `internal/hooks/hooks.go`, v3.5.0)
531576
0 commit comments