@plainconceptsplatform/agent-harness 2.5.0 → 2.5.1

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.
package/cli/utils/copy.js CHANGED
@@ -15,6 +15,24 @@ const NEVER_OVERWRITE = [
15
15
 
16
16
  const MARKER_COMMANDS = new Set(['.opencode/commands/ops-review.md', '.opencode/commands/ops-backlog.md'])
17
17
 
18
+ // Where a project may legitimately keep the doc instead of the repository root.
19
+ // Foundations puts both under ai/, and projects that follow it point their own
20
+ // AGENTS.md there.
21
+ const ROOT_DOCS = new Set(['ARCHITECTURE.md', 'DESIGN.md'])
22
+ const ALTERNATE_DOC_DIRS = ['ai', 'docs']
23
+
24
+ // Seeding the "NOT GENERATED YET, run /make-architecture" placeholder next to a
25
+ // real architecture document is worse than seeding nothing: pc-make-guardrails
26
+ // reads the root file as its primary source, and an agent that finds the
27
+ // placeholder there concludes the project has no architecture written down.
28
+ async function documentedElsewhere(destDir, fileName) {
29
+ if (!ROOT_DOCS.has(fileName)) return false
30
+ for (const directory of ALTERNATE_DOC_DIRS) {
31
+ if (await fse.pathExists(path.join(destDir, directory, fileName))) return true
32
+ }
33
+ return false
34
+ }
35
+
18
36
  function isTemplateTest(relativePath) {
19
37
  return relativePath.split(path.sep).join('/').startsWith('.opencode/plugins/') && relativePath.endsWith('.test.js')
20
38
  }
@@ -50,6 +68,7 @@ export async function copyContent(contentDir, destDir, platform, ctx = {}) {
50
68
  if (isTemplateTest(rel)) return false
51
69
  if (ctx.hasDesign && rel === 'DESIGN.md') return false
52
70
  if (ctx.hasArchitecture && rel === 'ARCHITECTURE.md') return false
71
+ if (await documentedElsewhere(destDir, rel)) return false
53
72
  // User-owned config files are never overwritten, even with forceOverwrite.
54
73
  // The update command calls writeModelsToConfigs separately to set the
55
74
  // model field in opencode.jsonc without destroying user additions.
@@ -139,13 +139,30 @@ async function checkPush(command, root, defaultBranch) {
139
139
  }
140
140
  }
141
141
 
142
+ // `/tmp/gh-aw/` is the agent workflow runtime's own working directory, not agent scratch.
143
+ //
144
+ // GitHub Agentic Workflows stages everything a worker is given there before the agent starts:
145
+ // the issue context, the open-issue list, the pull request diff, the review comments. The worker
146
+ // prompts name those paths and tell the agent to read them. This check tests the whole command
147
+ // string, so it cannot tell "write to /tmp" from "read from /tmp" — and a command that read one
148
+ // of those files and wrote the result anywhere at all was denied.
149
+ //
150
+ // The effect was total and silent. Three refine runs in a row spent their whole turn arguing
151
+ // with this guardrail and emitted nothing: the agent tried
152
+ // `jq -r .body /tmp/gh-aw/agent/issue-context.json > .opencode/.tmp/body.md`, was refused, tried
153
+ // an absolute path, was refused again, and gave up. The advice it is handed names `$REPO_ROOT`,
154
+ // which is unset on a GitHub Actions runner, so following it exactly could not work either.
155
+ //
156
+ // Exempting this one directory is not a hole in the rule. The rule exists so the next step can
157
+ // still find what the agent wrote, and `/tmp/gh-aw/` is exactly where the next step looks.
142
158
  function checkScratch(command) {
143
159
  const writesSomewhere = /(>>?|\btee\b|\bcp\b|\bmv\b|\bmkdir\b|\btouch\b|\bdd\b)/.test(command)
144
- const outsideRepo = /(\/tmp\/|\$TMPDIR|\$TEMP\b|%TEMP%|\bmktemp\b)/.test(command)
160
+ // Everywhere else stays blocked: /tmp outside gh-aw, $TMPDIR, $TEMP, %TEMP%, mktemp.
161
+ const outsideRepo = /(\/tmp\/(?!gh-aw\/)|\$TMPDIR|\$TEMP\b|%TEMP%|\bmktemp\b)/.test(command)
145
162
  if (writesSomewhere && outsideRepo) {
146
163
  deny(
147
164
  "Scratch files belong inside the repository, where the next step and the next agent can still find them.",
148
- "Write under `$REPO_ROOT/.opencode/.tmp/`.",
165
+ "Write under `$REPO_ROOT/.opencode/.tmp/`, or the workflow runtime's own `/tmp/gh-aw/`.",
149
166
  )
150
167
  }
151
168
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plainconceptsplatform/agent-harness",
3
- "version": "2.5.0",
3
+ "version": "2.5.1",
4
4
  "description": "Installs the Plain Concepts Platform Harness into any codebase, and keeps it up to date. Wires OpenCode, OpenSpec, codegraph, and agentmemory into a multi-agent workflow that runs on native parallel subagents.",
5
5
  "keywords": [
6
6
  "opencode",