@homericintelligence/athena-opencode 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/README.md +30 -17
  2. package/package.json +2 -2
  3. package/plugin.js +20 -5
  4. package/skills/TECHNICAL_ENGLISH.md +78 -0
  5. package/skills/_cli.py +33 -22
  6. package/skills/_plugin.json +1 -0
  7. package/skills/_support/docs/dependency-resolution.md +203 -0
  8. package/skills/_support/docs/policies/development.md +131 -0
  9. package/skills/_support/docs/policies/evidence-integrity.md +40 -0
  10. package/skills/_support/docs/principles/README.md +565 -0
  11. package/skills/_support/docs/principles/details/p001-kiss.md +114 -0
  12. package/skills/_support/docs/principles/details/p002-yagni.md +109 -0
  13. package/skills/_support/docs/principles/details/p003-dry.md +126 -0
  14. package/skills/_support/docs/principles/details/p004-solid.md +165 -0
  15. package/skills/_support/docs/principles/details/p005-modularity.md +123 -0
  16. package/skills/_support/docs/principles/details/p006-principle-of-least-astonishment.md +115 -0
  17. package/skills/_support/docs/principles/details/p007-subtraction-over-addition.md +113 -0
  18. package/skills/_support/docs/principles/details/p008-understand-before-subtracting.md +115 -0
  19. package/skills/_support/docs/principles/details/p009-general-mechanisms-over-special-cases.md +108 -0
  20. package/skills/_support/docs/principles/details/p010-scope-fidelity.md +117 -0
  21. package/skills/_support/docs/principles/details/p011-minimal-coherent-change.md +128 -0
  22. package/skills/_support/docs/principles/details/p012-evidence-before-modification.md +115 -0
  23. package/skills/_support/docs/principles/details/p013-avoid-hasty-abstractions.md +112 -0
  24. package/skills/_support/docs/principles/details/p014-preserve-unrequested-behavior.md +110 -0
  25. package/skills/_support/docs/principles/details/p015-architecture-conformance.md +124 -0
  26. package/skills/_support/docs/principles/details/p016-separation-of-concerns.md +125 -0
  27. package/skills/_support/docs/principles/details/p017-high-cohesion-low-coupling.md +130 -0
  28. package/skills/_support/docs/principles/details/p018-information-hiding.md +128 -0
  29. package/skills/_support/docs/principles/details/p019-explicit-contracts.md +134 -0
  30. package/skills/_support/docs/principles/details/p020-executable-architecture.md +130 -0
  31. package/skills/_support/docs/principles/details/p021-evolutionary-and-reversible-design.md +126 -0
  32. package/skills/_support/docs/principles/details/p022-test-behavior-not-implementation.md +129 -0
  33. package/skills/_support/docs/principles/details/p023-parameterized-table-driven-testing.md +129 -0
  34. package/skills/_support/docs/principles/details/p024-boundary-value-testing.md +128 -0
  35. package/skills/_support/docs/principles/details/p025-property-based-testing-for-invariants.md +133 -0
  36. package/skills/_support/docs/principles/details/p026-regression-before-repair.md +134 -0
  37. package/skills/_support/docs/principles/details/p027-deterministic-and-hermetic-tests.md +128 -0
  38. package/skills/_support/docs/principles/details/p028-test-failure-paths.md +133 -0
  39. package/skills/_support/docs/principles/details/p029-generalize-error-policy-preserve-specific-cause.md +131 -0
  40. package/skills/_support/docs/principles/details/p030-nearest-responsible-error-boundary.md +133 -0
  41. package/skills/_support/docs/principles/details/p031-propagate-rather-than-swallow.md +131 -0
  42. package/skills/_support/docs/principles/details/p032-handle-once-preserve-causality.md +137 -0
  43. package/skills/_support/docs/principles/details/p033-state-safe-failure-semantics.md +140 -0
  44. package/skills/_support/docs/principles/details/p034-fail-fast.md +132 -0
  45. package/skills/_support/docs/principles/details/p035-fail-secure-fail-closed.md +137 -0
  46. package/skills/_support/docs/principles/details/p036-graceful-degradation.md +137 -0
  47. package/skills/_support/docs/principles/details/p037-idempotency-before-retry.md +139 -0
  48. package/skills/_support/docs/principles/details/p038-bounded-retry.md +145 -0
  49. package/skills/_support/docs/principles/details/p039-bounded-waiting.md +151 -0
  50. package/skills/_support/docs/principles/details/p040-bounded-resources.md +138 -0
  51. package/skills/_support/docs/principles/details/p041-backpressure-and-load-shedding.md +141 -0
  52. package/skills/_support/docs/principles/details/p042-fault-isolation-bulkheads.md +140 -0
  53. package/skills/_support/docs/principles/details/p043-circuit-breakers.md +148 -0
  54. package/skills/_support/docs/principles/details/p044-atomicity-where-possible.md +141 -0
  55. package/skills/_support/docs/principles/details/p045-compensation-where-atomicity-is-impossible.md +163 -0
  56. package/skills/_support/docs/principles/details/p046-resumability.md +138 -0
  57. package/skills/_support/docs/principles/details/p047-observability-is-part-of-correctness.md +134 -0
  58. package/skills/_support/docs/principles/details/p048-secure-by-design.md +132 -0
  59. package/skills/_support/docs/principles/details/p049-secure-by-default.md +126 -0
  60. package/skills/_support/docs/principles/details/p050-least-privilege.md +123 -0
  61. package/skills/_support/docs/principles/details/p051-complete-mediation.md +124 -0
  62. package/skills/_support/docs/principles/details/p052-separation-of-duties.md +129 -0
  63. package/skills/_support/docs/principles/details/p053-validate-at-trust-boundaries.md +126 -0
  64. package/skills/_support/docs/principles/details/p054-defense-in-depth.md +135 -0
  65. package/skills/_support/docs/principles/details/p055-minimize-attack-surface.md +133 -0
  66. package/skills/_support/docs/principles/details/p056-secrets-stay-out-of-code-and-context.md +137 -0
  67. package/skills/_support/docs/principles/details/p057-supply-chain-integrity.md +135 -0
  68. package/skills/_support/docs/principles/details/p058-bounded-agent-authority.md +137 -0
  69. package/skills/_support/docs/principles/details/p059-data-is-not-instruction.md +130 -0
  70. package/skills/_support/docs/principles/details/p060-constrain-sub-agents.md +136 -0
  71. package/skills/_support/docs/principles/details/p061-separate-decision-from-high-impact-execution.md +131 -0
  72. package/skills/_support/docs/principles/details/p062-human-approval-for-irreversible-or-high-risk-actions.md +129 -0
  73. package/skills/_support/docs/principles/details/p063-requirement-to-code-traceability.md +116 -0
  74. package/skills/_support/docs/principles/details/p064-requirement-to-test-traceability.md +116 -0
  75. package/skills/_support/docs/principles/details/p065-verify-before-claiming-completion.md +131 -0
  76. package/skills/_support/docs/principles/details/p066-preserve-existing-work.md +114 -0
  77. package/skills/_support/docs/principles/details/p067-no-test-cheating.md +126 -0
  78. package/skills/_support/docs/principles/details/p068-no-validation-bypass.md +119 -0
  79. package/skills/_support/docs/principles/details/p069-independent-review-for-high-risk-changes.md +129 -0
  80. package/skills/_support/docs/principles/details/p070-code-health-must-not-regress.md +116 -0
  81. package/skills/_support/docs/principles/details/p071-consistency-over-personal-preference.md +117 -0
  82. package/skills/_support/docs/principles/details/p072-technical-evidence-over-preference.md +122 -0
  83. package/skills/_support/docs/principles/details/p073-optimize-only-with-evidence.md +123 -0
  84. package/skills/_support/docs/principles/details/p074-prefer-existing-mechanisms.md +121 -0
  85. package/skills/_support/docs/principles/details/p075-make-invalid-states-hard-to-represent.md +128 -0
  86. package/skills/_support/docs/principles/details/p076-parse-then-validate-then-operate.md +133 -0
  87. package/skills/_support/docs/principles/details/p077-separate-policy-from-mechanism.md +112 -0
  88. package/skills/_support/docs/principles/details/p078-single-source-of-truth.md +131 -0
  89. package/skills/_support/docs/principles/details/p079-explicit-ownership-and-lifetimes.md +124 -0
  90. package/skills/_support/docs/principles/details/p080-make-concurrency-deliberate.md +122 -0
  91. package/skills/_support/docs/principles/details/p081-forward-progress-with-safety.md +125 -0
  92. package/skills/_support/docs/principles/details/p082-design-for-cancellation.md +133 -0
  93. package/skills/_support/docs/principles/details/p083-irreversible-actions-last.md +124 -0
  94. package/skills/_support/docs/principles/details/p084-prefer-local-reasoning.md +131 -0
  95. package/skills/_support/docs/principles/details/p085-explicit-is-better-than-implicit.md +123 -0
  96. package/skills/_support/docs/principles/details/p086-readability-counts.md +113 -0
  97. package/skills/_support/docs/principles/details/p087-comments-explain-why-code-explains-what.md +120 -0
  98. package/skills/_support/docs/principles/details/p088-delete-dead-code.md +125 -0
  99. package/skills/_support/docs/principles/details/p089-delete-obsolete-configuration-and-dependencies.md +125 -0
  100. package/skills/_support/docs/principles/details/p090-prefer-negative-code.md +134 -0
  101. package/skills/_support/docs/principles/details/p091-test-driven-development.md +149 -0
  102. package/skills/_support/docs/review/README.md +63 -0
  103. package/skills/_support/docs/review/behavior-first-testing.md +78 -0
  104. package/skills/_support/docs/review/common.md +400 -0
  105. package/skills/_support/docs/review/design-docs.md +74 -0
  106. package/skills/_support/docs/review/issue-planning.md +247 -0
  107. package/skills/_support/docs/review/language-routing.md +141 -0
  108. package/skills/_support/docs/review/repository-scorecard.md +170 -0
  109. package/skills/advise/SKILL.md +108 -74
  110. package/skills/advise/scripts/list_retrievable_skills.py +20 -8
  111. package/skills/advise/scripts/resolve_knowledge_checkout.py +533 -0
  112. package/skills/brainstorm/SKILL.md +163 -127
  113. package/skills/change-review/SKILL.md +91 -71
  114. package/skills/change-review/references/scope-resolution.md +69 -46
  115. package/skills/change-review/scripts/resolve_scope.py +144 -84
  116. package/skills/finalize-plan/SKILL.md +205 -139
  117. package/skills/git-worktrees/SKILL.md +100 -80
  118. package/skills/git-worktrees/scripts/prepare_worktree.py +34 -15
  119. package/skills/issue-review/SKILL.md +136 -79
  120. package/skills/learn/SKILL.md +359 -192
  121. package/skills/myrmidon-swarm/SKILL.md +126 -86
  122. package/skills/plan-issue/SKILL.md +122 -81
  123. package/skills/pr-review/SKILL.md +184 -116
  124. package/skills/pr-review/references/criteria.md +61 -37
  125. package/skills/pr-review/references/delivery.md +277 -101
  126. package/skills/pr-review/references/evidence.md +346 -149
  127. package/skills/pr-review/references/prevalidated.md +93 -61
  128. package/skills/pr-review/scripts/collect_evidence.py +312 -162
  129. package/skills/pr-review/scripts/deliver_go.py +701 -0
  130. package/skills/pr-review/scripts/diff_context.py +34 -15
  131. package/skills/pr-review/scripts/materialize_snapshot.py +141 -130
  132. package/skills/pr-review/scripts/pr_identity.py +27 -15
  133. package/skills/pr-review/scripts/resolve_pr.py +77 -41
  134. package/skills/realign/SKILL.md +516 -0
  135. package/skills/realign/references/aislop-integration.md +215 -0
  136. package/skills/realign/references/architecture-and-structure.md +271 -0
  137. package/skills/realign/references/control-flow-and-errors.md +344 -0
  138. package/skills/realign/references/tests-dependencies-and-security.md +261 -0
  139. package/skills/realign/scripts/resolve_assessment.py +1525 -0
  140. package/skills/repo-review/SKILL.md +202 -131
  141. package/skills/simplify/SKILL.md +174 -0
  142. package/skills/systematic-debugging/SKILL.md +212 -192
  143. package/skills/systematic-debugging/scripts/repository_evidence.py +26 -8
  144. package/skills/test-driven-development/SKILL.md +126 -96
  145. package/skills/tidy/SKILL.md +104 -59
  146. package/skills/tidy/scripts/run_tidy.py +54 -6
package/README.md CHANGED
@@ -1,13 +1,20 @@
1
1
  # athena-opencode
2
2
 
3
- [Athena](https://github.com/HomericIntelligence/Athena) workflow skills packaged as an
4
- [opencode](https://opencode.ai) plugin. Installing this plugin places the full canonical skill
5
- corpus under your opencode configuration directory, where opencode discovers and loads it natively.
3
+ [Athena](https://github.com/HomericIntelligence/Athena) packages its workflow skills as an
4
+ [opencode](https://opencode.ai) plugin. The plugin contains the full canonical skill corpus. It puts
5
+ the corpus in the opencode configuration directory. Opencode finds and loads the corpus there.
6
+
7
+ Athena uses the
8
+ [ASD-STE100 technical-English policy](skills/TECHNICAL_ENGLISH.md)
9
+ for its English technical prose.
6
10
 
7
11
  ## Install
8
12
 
9
- Add the package to the `plugin` array of your opencode configuration
10
- (`~/.config/opencode/opencode.json` or a project `opencode.json`):
13
+ Add the package to the `plugin` array in the opencode configuration. Use one of these configuration
14
+ files:
15
+
16
+ - `~/.config/opencode/opencode.json`; or
17
+ - a project `opencode.json`.
11
18
 
12
19
  ```json
13
20
  {
@@ -16,29 +23,35 @@ Add the package to the `plugin` array of your opencode configuration
16
23
  }
17
24
  ```
18
25
 
19
- Quit and restart opencode. On startup the plugin copies the bundled `skills/` corpus to:
26
+ Quit opencode. Then, restart opencode. During startup, the plugin copies the bundled `skills/` corpus
27
+ to this location:
20
28
 
21
29
  ```
22
30
  $XDG_CONFIG_HOME/opencode/skills/athena/
23
31
  ```
24
32
 
25
- (`~/.config/opencode/skills/athena/` by default.) The plugin only ever writes inside that
26
- `athena/` namespace; other skills in your configuration are never touched. Each restart refreshes
27
- the namespace to match the installed plugin version, so upgrading the npm package upgrades the
28
- skills.
33
+ If `XDG_CONFIG_HOME` does not have a value, the target is
34
+ `~/.config/opencode/skills/athena/`. The plugin writes only in the `athena/` namespace. It does not
35
+ change other skills in your configuration. At each restart, the plugin makes the namespace agree
36
+ with the installed plugin version. Thus, a package update also updates the skills.
29
37
 
30
38
  ## Use
31
39
 
32
- Invoke skills through opencode's native skill mechanism, for example by asking opencode to use the
33
- `repo-review`, `pr-review`, or `plan-issue` skill. See the root
34
- [`README.md`](https://github.com/HomericIntelligence/Athena#readme) for the full skill catalog,
35
- dependency requirements (Git, Python 3.13, authenticated `gh` for forge routes), and capability
36
- fallbacks.
40
+ Use the native opencode skill mechanism. For example, ask opencode to use the `repo-review`,
41
+ `pr-review`, or `plan-issue` skill. See the root
42
+ [`README.md`](https://github.com/HomericIntelligence/Athena#readme) for this information:
43
+
44
+ - the full skill catalog;
45
+ - dependency requirements for Git and Python 3.13;
46
+ - the authenticated GitHub CLI (`gh`) requirement for forge routes; and
47
+ - capability fallbacks.
37
48
 
38
49
  ## Uninstall
39
50
 
40
- Remove `"@homericintelligence/athena-opencode"` from the `plugin` array, restart opencode, and delete
41
- `opencode/skills/athena/` from your configuration directory if you want the files gone immediately.
51
+ 1. Remove `"@homericintelligence/athena-opencode"` from the `plugin` array.
52
+ 2. Restart opencode.
53
+ 3. To remove the files immediately, delete `opencode/skills/athena/` from your configuration
54
+ directory.
42
55
 
43
56
  ## License
44
57
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@homericintelligence/athena-opencode",
3
- "version": "0.5.0",
4
- "description": "Athena workflow skills packaged as an opencode plugin.",
3
+ "version": "0.5.2",
4
+ "description": "Athena provides workflow skills as an opencode plugin.",
5
5
  "license": "BSD-3-Clause",
6
6
  "type": "module",
7
7
  "main": "plugin.js",
package/plugin.js CHANGED
@@ -1,4 +1,11 @@
1
- import { cpSync, existsSync, mkdirSync, readdirSync, rmSync } from "node:fs";
1
+ import {
2
+ cpSync,
3
+ existsSync,
4
+ mkdirSync,
5
+ readdirSync,
6
+ rmSync,
7
+ statSync,
8
+ } from "node:fs";
2
9
  import { homedir } from "node:os";
3
10
  import { dirname, join, resolve } from "node:path";
4
11
  import { fileURLToPath } from "node:url";
@@ -26,7 +33,7 @@ export function syncSkills() {
26
33
  const target = installTarget();
27
34
  if (!existsSync(join(source, "_cli.py"))) {
28
35
  throw new Error(
29
- `Athena skill corpus is missing next to plugin.js: ${source}`,
36
+ `The plugin cannot find the Athena skills next to plugin.js: '${source}'.`,
30
37
  );
31
38
  }
32
39
  mkdirSync(dirname(target), { recursive: true });
@@ -39,7 +46,9 @@ async function athenaPlugin() {
39
46
  try {
40
47
  syncSkills();
41
48
  } catch (error) {
42
- console.warn(`[athena-opencode] skill installation failed: ${error}`);
49
+ console.warn(
50
+ `[athena-opencode] The plugin could not install the skills: ${error}`,
51
+ );
43
52
  }
44
53
  return {};
45
54
  }
@@ -47,8 +56,14 @@ async function athenaPlugin() {
47
56
  export default athenaPlugin;
48
57
 
49
58
  export function bundledSkillNames() {
50
- return readdirSync(bundledSkillsRoot(), { withFileTypes: true })
51
- .filter((entry) => entry.isDirectory())
59
+ const root = bundledSkillsRoot();
60
+ return readdirSync(root, { withFileTypes: true })
61
+ .filter(
62
+ (entry) =>
63
+ entry.isDirectory() &&
64
+ existsSync(join(root, entry.name, "SKILL.md")) &&
65
+ statSync(join(root, entry.name, "SKILL.md")).isFile(),
66
+ )
52
67
  .map((entry) => entry.name)
53
68
  .sort();
54
69
  }
@@ -0,0 +1,78 @@
1
+ # ASD-STE100 technical-English policy
2
+
3
+ All Athena English technical prose must follow
4
+ [ASD-STE100 Simplified Technical English](https://www.asd-ste100.org/). This requirement applies to
5
+ skills, agent directions, public documents, user messages that a skill produces, and text in a user
6
+ interface.
7
+
8
+ The literal text that this policy identifies does not have to obey it.
9
+
10
+ ## Authority
11
+
12
+ Use the current official issue of ASD-STE100 as the authority. Request a copy from the
13
+ [official download page](https://www.asd-ste100.org/STE_downloads.html).
14
+
15
+ This repository policy does not copy or replace the standard. It does not replace approved
16
+ training. Repository checks can find Markdown errors, broken package contracts, and some style
17
+ risks. The checks do not certify conformance to ASD-STE100.
18
+
19
+ ## Required method
20
+
21
+ Use these steps when you write or change technical prose:
22
+
23
+ 1. Read the applicable technical source before you write.
24
+ 2. Use approved words with their approved meanings and parts of speech.
25
+ 3. Use a technical noun or a technical verb when the approved dictionary has no necessary term.
26
+ 4. Use one term for one meaning.
27
+ 5. Do not use a different synonym for the same item or action.
28
+ 6. Use American English spelling unless an exact external name uses a different spelling.
29
+ 7. Use active voice when you know the actor.
30
+ 8. Use the imperative form for a direct instruction.
31
+ 9. Put a condition before the related action when the reader must know the condition first.
32
+ 10. Give one primary instruction in each numbered step.
33
+ 11. Keep sentences short.
34
+ 12. Split a sentence when it contains more than one independent idea.
35
+ 13. Use a vertical list when it makes complex information easier to identify.
36
+ 14. Avoid an `-ing` form when an approved, unambiguous form gives the same meaning.
37
+ 15. Define each abbreviation at its first use unless the intended readers always know it.
38
+ 16. Keep the technical meaning.
39
+ 17. Do not remove a necessary safety, evidence, permission, or failure condition to make a sentence
40
+ shorter.
41
+ 18. Review the result against the current official standard.
42
+
43
+ ## Literal text
44
+
45
+ Do not change literal text only to make it conform to this policy. Literal text includes:
46
+
47
+ - programming-language syntax and generated code;
48
+ - commands, options, identifiers, paths, URLs, and API field names;
49
+ - machine-readable markers, schemas, and data values;
50
+ - legal text, licenses, and required notices;
51
+ - attributed quotations; and
52
+ - historical records that must preserve their original text.
53
+
54
+ A message for a user or an agent is technical prose even when source code contains it. This rule
55
+ applies to command help, error messages, status messages, prompts, and user-interface labels.
56
+
57
+ Write the prose around literal text in accordance with ASD-STE100.
58
+
59
+ Use code formatting or a quotation format to make the literal boundary clear.
60
+
61
+ ## Conflict and verification
62
+
63
+ Technical accuracy, safety controls, security controls, evidence rules, and higher-authority
64
+ instructions take precedence. If simplified wording changes the required meaning, use these steps:
65
+
66
+ 1. Keep the required meaning.
67
+ 2. Rewrite the sentence.
68
+
69
+ Ask for a technical review when you cannot remove the ambiguity.
70
+
71
+ If you cannot use the current official standard:
72
+
73
+ - Apply this policy.
74
+ - Report the verification gap.
75
+
76
+ Do not state that the text conforms to ASD-STE100.
77
+
78
+ Do not state that a person or tool certified or verified ASD-STE100 conformance.
package/skills/_cli.py CHANGED
@@ -1,4 +1,4 @@
1
- """Shared argparse construction for Athena's executable helpers."""
1
+ """This module provides shared command-line support for Athena helpers."""
2
2
 
3
3
  from __future__ import annotations
4
4
 
@@ -16,26 +16,29 @@ PLUGIN_ROOT = Path(__file__).resolve().parent.parent
16
16
  def run_command(
17
17
  arguments: Sequence[str], **kwargs: Any
18
18
  ) -> subprocess.CompletedProcess[str]:
19
- """Run an external command or identify a missing required capability."""
19
+ """Run an external command and report a missing required capability."""
20
20
  if not arguments:
21
- raise RuntimeError("required command is empty")
21
+ raise RuntimeError("The required command is empty.")
22
22
  try:
23
23
  check = kwargs.pop("check", False)
24
24
  return subprocess.run(arguments, check=check, **kwargs)
25
25
  except FileNotFoundError as error:
26
26
  command = error.filename or arguments[0]
27
- raise RuntimeError(f"required command unavailable: {command}") from error
27
+ raise RuntimeError(
28
+ f"The required command is not available: '{command}'."
29
+ ) from error
28
30
 
29
31
 
30
32
  def git_read_environment() -> dict[str, str]:
31
- """Return a hermetic environment for immutable, non-interactive Git reads."""
33
+ """Return an isolated environment for immutable, non-interactive Git reads."""
32
34
  environment = {
33
35
  key: value for key, value in os.environ.items() if not key.startswith("GIT_")
34
36
  }
35
37
  # `--no-replace-objects` does not disable deprecated graft files. Force Git
36
- # to read an empty graft source. Strip every inherited GIT_* setting first:
37
- # location, object, index, config, attribute, pathspec, and transport
38
- # overrides can otherwise redirect or change a supposedly immutable read.
38
+ # to read an empty graft source. First, remove each inherited `GIT_*`
39
+ # setting. These settings can redirect or change an immutable read. They
40
+ # include location, object, index, configuration, attribute, pathspec, and
41
+ # transport settings.
39
42
  environment.update(
40
43
  {
41
44
  "GIT_ATTR_NOSYSTEM": "1",
@@ -58,7 +61,7 @@ def git_read_arguments() -> tuple[str, ...]:
58
61
 
59
62
 
60
63
  def require_complete_git_history(*, cwd: Path | None = None) -> None:
61
- """Reject shallow history before deriving immutable ancestry evidence."""
64
+ """Reject shallow history before calculation of immutable ancestry evidence."""
62
65
  result = run_command(
63
66
  ["git", *git_read_arguments(), "rev-parse", "--is-shallow-repository"],
64
67
  capture_output=True,
@@ -69,20 +72,21 @@ def require_complete_git_history(*, cwd: Path | None = None) -> None:
69
72
  )
70
73
  if result.returncode != 0:
71
74
  message = (
72
- result.stderr.strip() or "git rev-parse --is-shallow-repository failed"
75
+ result.stderr.strip()
76
+ or "The git rev-parse --is-shallow-repository command failed."
73
77
  )
74
78
  raise RuntimeError(message)
75
79
  if result.stdout.strip() != "false":
76
80
  raise RuntimeError(
77
- "immutable review evidence requires a non-shallow repository; "
78
- "use a complete source snapshot"
81
+ "The immutable review evidence needs a non-shallow repository. "
82
+ "Use a complete source snapshot."
79
83
  )
80
84
 
81
85
 
82
86
  def require_unambiguous_git_merge_base(
83
87
  base_oid: str, head_oid: str, *, cwd: Path | None = None
84
88
  ) -> str:
85
- """Return the sole immutable merge base or reject ambiguous topology."""
89
+ """Return the only immutable merge base or reject an ambiguous history."""
86
90
  result = run_command(
87
91
  [
88
92
  "git",
@@ -99,23 +103,28 @@ def require_unambiguous_git_merge_base(
99
103
  check=False,
100
104
  )
101
105
  if result.returncode != 0:
102
- message = result.stderr.strip() or "git merge-base failed"
106
+ message = result.stderr.strip() or "The git merge-base command failed."
103
107
  raise RuntimeError(message)
104
108
  merge_bases = result.stdout.splitlines()
105
109
  if len(merge_bases) != 1 or not merge_bases[0]:
106
110
  raise RuntimeError(
107
- "immutable review evidence requires one unambiguous merge base"
111
+ "The immutable review evidence requires one unambiguous merge base."
108
112
  )
109
113
  return merge_bases[0]
110
114
 
111
115
 
112
116
  def plugin_version() -> str:
113
- """Return the version from the canonical Codex plugin manifest."""
114
- manifest = PLUGIN_ROOT / ".codex-plugin" / "plugin.json"
117
+ """Return this corpus's generated version or its adjacent canonical manifest."""
118
+ corpus = Path(__file__).resolve().parent
119
+ manifest = corpus / "_plugin.json"
120
+ if not manifest.exists() and corpus.name == "skills":
121
+ manifest = PLUGIN_ROOT / ".codex-plugin" / "plugin.json"
115
122
  document = json.loads(manifest.read_text(encoding="utf-8"))
116
123
  version = document.get("version") if isinstance(document, dict) else None
117
- if not isinstance(version, str):
118
- raise TypeError(f"plugin manifest has no string version: {manifest}")
124
+ if not isinstance(version, str) or not version.strip():
125
+ raise TypeError(
126
+ f"The plugin manifest does not contain a string version: '{manifest}'."
127
+ )
119
128
  return version
120
129
 
121
130
 
@@ -132,9 +141,11 @@ class _PluginVersionAction(argparse.Action):
132
141
  del namespace, values, option_string
133
142
  try:
134
143
  version = plugin_version()
135
- except (OSError, TypeError, json.JSONDecodeError) as error:
144
+ except (OSError, TypeError, UnicodeError, json.JSONDecodeError) as error:
136
145
  parser.exit(
137
- 1, f"{parser.prog}: error: cannot read plugin version: {error}\n"
146
+ 1,
147
+ f"{parser.prog}: error: The tool cannot read the plugin version: "
148
+ f"{error}\n",
138
149
  )
139
150
  print(f"{parser.prog} {version}")
140
151
  parser.exit(0)
@@ -147,6 +158,6 @@ def argument_parser(*, description: str | None = None) -> argparse.ArgumentParse
147
158
  "--version",
148
159
  action=_PluginVersionAction,
149
160
  nargs=0,
150
- help="show the Athena plugin version and exit",
161
+ help="Show the Athena plugin version and exit.",
151
162
  )
152
163
  return parser
@@ -0,0 +1 @@
1
+ {"version": "0.5.2"}
@@ -0,0 +1,203 @@
1
+ # Repository resolution
2
+
3
+ Apply the [ASD-STE100 technical-English policy](../../TECHNICAL_ENGLISH.md) to all English technical prose
4
+ in this document.
5
+
6
+ **Why:** Athena must use trusted and current repositories when it changes Mnemosyne or executes
7
+ Hephaestus. Read-only knowledge can use a validated local checkout and then try a best-effort
8
+ refresh. Athena must not report an unverified remote or stale checkout as current.
9
+
10
+ ## At a glance
11
+
12
+ During normal resolution for a write or automation execution, Athena does these steps:
13
+
14
+ 1. It resolves a trusted owner.
15
+ 2. It synchronizes an exact checkout.
16
+ 3. It binds use to the reported revision.
17
+
18
+ A trust, authentication, checkout, or update failure stops that write or automation execution.
19
+
20
+ All read-only Mnemosyne paths validate the local checkout first. If `gh`, authentication, and
21
+ network access are available, Athena then tries a best-effort refresh. If the refresh cannot run
22
+ or fails, Athena keeps the validated local checkout and reports the freshness limit. This path
23
+ must do these actions:
24
+
25
+ - bind use to the current `HEAD`;
26
+ - report the current `HEAD` or the refreshed revision;
27
+ - report the freshness and trust limits;
28
+ - never substitute a different repository; and
29
+ - never make a durable write from that checked state.
30
+
31
+ If local knowledge is unavailable, stop only knowledge retrieval. Continue the primary task. The
32
+ `learn` skill can classify a candidate, but it must complete normal resolution and duplicate checks
33
+ before a durable write.
34
+
35
+ ```mermaid
36
+ flowchart LR
37
+ A["Resolve dependency"] --> B{"Read-only Mnemosyne use?"}
38
+ B -->|yes| C{"Is a local checkout readable?"}
39
+ C -->|no| E["Report no local guidance; continue primary task"]
40
+ C -->|yes| D["Bind local HEAD and report limits"]
41
+ D --> F{"Can gh auth and discovery run?"}
42
+ F -->|yes| G["Try refresh, then report the updated revision or the local fallback"]
43
+ F -->|no| H["Keep the validated local revision and report the freshness limit"]
44
+ B -->|no| I{"Is there an explicit owner?"}
45
+ I -->|yes| J["Validate override"]
46
+ I -->|no| K{"Is there a trusted organization fork?"}
47
+ K -->|yes| L["Use maintained fork"]
48
+ K -->|no| M["Use canonical upstream"]
49
+ J --> N["Verify origin and clean checkout"]
50
+ L --> N
51
+ M --> N
52
+ N --> O["Fetch, fast-forward, and bind SHA"]
53
+ O --> P["Revalidate automatic-fork trust before use"]
54
+ ```
55
+
56
+ ## Component details
57
+
58
+ ### Owner selection
59
+
60
+ For a route that needs normal resolution of dependency `<Repository>` with environment override
61
+ `<OWNER_VARIABLE>`, use these steps:
62
+
63
+ 1. If `<OWNER_VARIABLE>` is not empty, select `<value>/<Repository>`.
64
+
65
+ - Before you use the owner in a path or command, validate it as a GitHub owner name.
66
+ - If the explicit override is not valid, report an error.
67
+ - If the explicit override is not valid, stop.
68
+ - If the explicit override is not valid, do not use a fallback.
69
+ - The owner name must meet these requirements:
70
+
71
+ - It contains 1 through 39 characters.
72
+ - It contains only ASCII letters, digits, or single hyphens.
73
+ - It does not start or end with a hyphen.
74
+
75
+ 2. If `<OWNER_VARIABLE>` is empty, get the current repository owner with this command:
76
+
77
+ ```bash
78
+ gh repo view --json owner --jq .owner.login
79
+ ```
80
+
81
+ Use `<current-owner>/<Repository>` only when all these automatic-fork trust gates pass:
82
+
83
+ - The `owner.type` of the current repository is `Organization` and not `User`.
84
+ - The `viewerPermission` of the authenticated viewer on the current repository is `WRITE` (push),
85
+ `MAINTAIN`, or `ADMIN`.
86
+ - GitHub confirms that the candidate is a fork. Its `parent.full_name` must be
87
+ `HomericIntelligence/<Repository>`.
88
+ - Athena can resolve and report the candidate repository and the tip SHA of its remote default
89
+ branch.
90
+
91
+ 3. If no trusted override or automatic fork applies, use `HomericIntelligence/<Repository>`.
92
+
93
+ Do not automatically select a repository with the same name in these conditions:
94
+
95
+ - The owner of the current repository is a user.
96
+ - The viewer has read, triage, or no permission.
97
+ - Athena cannot prove canonical ancestry.
98
+
99
+ Use repository metadata to make the fork decision. Do not use only the repository name:
100
+
101
+ ```bash
102
+ current_owner=$(gh repo view --json owner --jq '.owner.login')
103
+ gh api "repos/${current_owner}/<Repository>" \
104
+ --jq '.fork == true and .parent.full_name == "HomericIntelligence/<Repository>"'
105
+ ```
106
+
107
+ Only the literal result `true` passes the ancestry check. Use structured application programming
108
+ interface (API) output. Quote each derived value. Resolve these values:
109
+
110
+ - the `owner.type` of the current repository;
111
+ - the `viewerPermission` of the authenticated viewer;
112
+ - the `.default_branch` of the candidate; and
113
+ - the exact tip `.sha` of that branch.
114
+
115
+ The fork can contain modified content after all automatic trust gates pass. If the same-owner
116
+ candidate is missing or not eligible, use the canonical upstream repository. If an API or
117
+ authentication error prevents a trustworthy decision, treat the error as fatal and stop.
118
+
119
+ An explicit owner override is an explicit trust decision. It can select custom fork content without
120
+ the organization and viewer-permission gate. Before you use a resolved dependency, report this
121
+ information:
122
+
123
+ - the exact repository;
124
+ - the commit SHA; and
125
+ - the trust basis: `explicit override`, `maintained organization fork`, or `canonical upstream`.
126
+
127
+ ### Dependency map
128
+
129
+ | Purpose | Repository | Override | Checkout |
130
+ | --- | --- | --- | --- |
131
+ | Knowledge | `Mnemosyne` | `HOMERIC_INTELLIGENCE_MNEMOSYNE_OWNER` | `$HOME/.agent_brain/knowledge` |
132
+ | Automation | `Hephaestus` | `HOMERIC_INTELLIGENCE_HEPHAESTUS_OWNER` | `$HOME/.agent_brain/automation` |
133
+
134
+ ### Checkout and revalidation
135
+
136
+ Normal resolution applies to Mnemosyne delivery and Hephaestus execution. It requires these
137
+ capabilities:
138
+
139
+ - authenticated GitHub CLI (`gh`);
140
+ - `git`; and
141
+ - network access.
142
+
143
+ Create `$HOME/.agent_brain` when it is necessary. If the checkout is absent, clone the resolved
144
+ repository. For an existing checkout, do these checks and actions:
145
+
146
+ - Require `origin` to identify the resolved `owner/repository`.
147
+ - Do not overwrite local changes or silently change the remote.
148
+ - Fetch `origin`.
149
+ - Resolve the default branch of `origin`.
150
+ - Fast-forward that branch.
151
+ - Report the resolved repository and commit SHA.
152
+
153
+ For an automatically selected same-owner fork, repeat the trust checks immediately before use. Do
154
+ this before you write knowledge or execute automation. Re-query these values:
155
+
156
+ - the Organization owner of the current repository;
157
+ - the permission of the viewer;
158
+ - the `parent.full_name` of the candidate;
159
+ - the resolved repository identity;
160
+ - the default branch; and
161
+ - the tip SHA.
162
+
163
+ Require these values to agree with the reported trust decision. Require the checked-out commit to
164
+ agree with the re-queried tip SHA. Stop if a value does not agree. This check closes the race between
165
+ resolution and use.
166
+
167
+ ### Read-only knowledge access
168
+
169
+ Use this path for all read-only Mnemosyne retrieval. Inspect the existing checkout first. Bind use
170
+ to the current `HEAD`. If `gh`, authentication, and network access are available, try a refresh. If
171
+ the refresh cannot run or fails, keep the validated local checkout and report the freshness limit.
172
+
173
+ Do not require the local checkout to have the newest Mnemosyne revision. Do not require its
174
+ revision to agree with the installed Athena revision. The installed skill supplies its own
175
+ retrieval contract.
176
+
177
+ Report this information:
178
+
179
+ - the checkout;
180
+ - the revision;
181
+ - the trust basis or trust uncertainty; and
182
+ - the freshness limit.
183
+
184
+ If the checkout is missing or inspection fails, stop the dependent knowledge retrieval. Continue the
185
+ primary task. `learn` can classify an undelivered candidate, but it cannot make a duplicate decision
186
+ or publish a write until normal resolution succeeds.
187
+
188
+ For Hephaestus execution and the `learn` delivery boundary, these conditions are fatal:
189
+
190
+ - an authentication failure;
191
+ - a missing repository;
192
+ - a fork relationship that is not valid;
193
+ - an unexpected `origin`;
194
+ - conflicting local state;
195
+ - a clone failure;
196
+ - a fetch failure; or
197
+ - a fast-forward failure.
198
+
199
+ Read-only local access never permits pull-request creation before upstream synchronization.
200
+
201
+ Mnemosyne writes use isolated worktrees and always end in a pull request. Athena reads or executes
202
+ Hephaestus from its canonical checkout. Athena never edits Hephaestus unless the user explicitly asks
203
+ for a Hephaestus change.