feat(project): --gate reaches the build, and the bundle says which one
`project.create` called `build()` with five keyword arguments and no `gate=`, so `okf project` screened by the package default and nothing anywhere said that was a choice rather than the only option. The gate is not a segmentation rule -- it is a screen about whether a document may be persisted at all -- so it is the one flag this command owns that may move a bundle's bytes, and the module docstring, the README paragraph and the test file's own claim are corrected rather than left standing beside the new flag. The default is `okf build`'s default, so an unflagged `okf project` is the bytes it always was; the byte-equality invariant against `okf build` holds unchanged. An unknown gate name still raises `gate_invalid` rather than falling back -- a fallback reproduces the defect with an extra step. Tests first, all three red: the gate name read back out of the bundle's own `log.md` (not out of the call), the flag parsed by this command's parser, and the unknown name refused. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
404bed26e2
commit
1c97e57212
3 changed files with 66 additions and 11 deletions
|
|
@ -1,10 +1,18 @@
|
|||
"""One folder of documents in, one questionable project out, in one command.
|
||||
|
||||
`okf project <folder>` is `okf build` followed by `okf skill`, plus the summary
|
||||
a person needs in order to know what they just got. It adds no rule of its own
|
||||
and owns no flag that changes a bundle's bytes: the build runs on THIS
|
||||
package's default, so a project bundle and an `okf build` bundle of the same
|
||||
folder at the same stamp are the same bytes.
|
||||
a person needs in order to know what they just got. It adds no rule of its
|
||||
own: the build runs on THIS package's defaults, so a project bundle and an
|
||||
`okf build` bundle of the same folder at the same stamp are the same bytes.
|
||||
|
||||
**One flag here DOES move a bundle's bytes, and it is stated rather than
|
||||
implied: `--gate`.** Every other flag `okf build` owns is deliberately absent,
|
||||
for the reason above -- two build paths would leave every measurement report
|
||||
pinned to a bundle nobody produces. The gate is different in kind: it is not a
|
||||
rule about how a document is cut but a screen about whether a document may be
|
||||
persisted at all, and a command that cannot reach it screens by the package
|
||||
default while saying nothing about it. The default is `okf build`'s default,
|
||||
so an unflagged `okf project` is the bytes it always was.
|
||||
|
||||
**Why a third command rather than a documented three-step.** The three-step
|
||||
existed and was measured on a reader: set `PYTHONPATH`, take a snapshot of a
|
||||
|
|
@ -34,8 +42,8 @@ import unicodedata
|
|||
from pathlib import Path
|
||||
|
||||
from . import consume, skill
|
||||
from .cli import DEFAULT_STAMP, build
|
||||
from .corpus import CorpusReport
|
||||
from .cli import DEFAULT_GATE, DEFAULT_STAMP, build
|
||||
from .corpus import GATE_NAMES, CorpusReport
|
||||
from .errors import IngestError
|
||||
from .inbox import walk_inbox
|
||||
from .profiles import SEGMENTED_OKF_V0_2
|
||||
|
|
@ -176,6 +184,7 @@ def create(
|
|||
out: Path,
|
||||
bundle_id: str | None = None,
|
||||
ingested_at: str = DEFAULT_STAMP,
|
||||
gate: str = DEFAULT_GATE,
|
||||
force: bool = False,
|
||||
) -> tuple[Path, Path, str]:
|
||||
"""Build the bundle, generate the skill, return both paths and the summary.
|
||||
|
|
@ -191,6 +200,7 @@ def create(
|
|||
ingested_at=ingested_at,
|
||||
bundle_id=identity,
|
||||
okf_version=PROJECT_OKF_VERSION,
|
||||
gate=gate,
|
||||
)
|
||||
if report.conservation_failed:
|
||||
raise IngestError(
|
||||
|
|
@ -230,6 +240,16 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
|
|||
default=DEFAULT_STAMP,
|
||||
help=f"stamped verbatim. Default {DEFAULT_STAMP}: deterministic, never the clock",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--gate",
|
||||
choices=GATE_NAMES,
|
||||
default=DEFAULT_GATE,
|
||||
help=(
|
||||
"the persist gate every concept body passes before it is written, "
|
||||
f"as `okf build` takes it. Default {DEFAULT_GATE}. `none` screens "
|
||||
"NOTHING; the name is written into the bundle's log.md either way"
|
||||
),
|
||||
)
|
||||
parser.add_argument(
|
||||
"--force", action="store_true", help="replace an existing SKILL.md at the destination"
|
||||
)
|
||||
|
|
@ -248,6 +268,7 @@ def main(argv: list[str] | None = None) -> int:
|
|||
out=out,
|
||||
bundle_id=args.bundle_id,
|
||||
ingested_at=args.ingested_at,
|
||||
gate=args.gate,
|
||||
force=args.force,
|
||||
)
|
||||
except (IngestError, consume.ConsumeError, skill.SkillError) as exc:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue